CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 07/08/07 20:53:11
Modified files: . : ChangeLog Makefile.am libbase : jpeg.cpp zlib_adapter.cpp server : fill_style.cpp fill_style.h matrix.cpp movie_instance.cpp rect.cpp sprite_instance.cpp stream.h styles.cpp styles.h types.cpp types.h server/parser : action_buffer.cpp morph2_character_def.cpp morph2_character_def.h shape_character_def.cpp Log message: * server/sprite_instance.cpp (processCompletedLoadVariableRequest): fix attempt to increment past-the-end iterator. * libbase/zlib_adaptar.cpp: don't hang on corrupted input. * libbase/jpeg.{cpp,h}: don't segfault on corrupted input. * server/matrix.cpp (read): add TODO item (check input) * server/rect.cpp (read): add TODO item (check input) * server/movie_instance.cpp (advance): warn only once about movie containing no frames. * server/parser/morph2_character_def.{cpp,h} (read): document, don't read past end of tag. * server/stream.h (read_variable_count): document and add integrity checks. Add a GNASH_TRUST_SWF macro to turn ensureBytes to a no-op. * server/parser/shape_character_def.cpp (read_fill_styles, read_line_styles, read): don't read past end of tag. Don't try to recover if an exception is thrown by fill style parser. * server/styles.{cpp,h} (line_style::read): don't read past end of tag. * server/fill_style.{cpp,h} (read): don't read past end of tag. * server/types.{cpp,h} (rgba::read_rgba, rgbe::read): don't read past end of tag. * server/parser/action_buffer.cpp (read): don't read past end of tag. * Makefile.am: don't list 'doc' twice in subdirs. Fixes 'distclean' rule. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3960&r2=1.3961 http://cvs.savannah.gnu.org/viewcvs/gnash/Makefile.am?cvsroot=gnash&r1=1.86&r2=1.87 http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/jpeg.cpp?cvsroot=gnash&r1=1.16&r2=1.17 http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/zlib_adapter.cpp?cvsroot=gnash&r1=1.16&r2=1.17 http://cvs.savannah.gnu.org/viewcvs/gnash/server/fill_style.cpp?cvsroot=gnash&r1=1.6&r2=1.7 http://cvs.savannah.gnu.org/viewcvs/gnash/server/fill_style.h?cvsroot=gnash&r1=1.7&r2=1.8 http://cvs.savannah.gnu.org/viewcvs/gnash/server/matrix.cpp?cvsroot=gnash&r1=1.16&r2=1.17 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_instance.cpp?cvsroot=gnash&r1=1.14&r2=1.15 http://cvs.savannah.gnu.org/viewcvs/gnash/server/rect.cpp?cvsroot=gnash&r1=1.12&r2=1.13 http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.303&r2=1.304 http://cvs.savannah.gnu.org/viewcvs/gnash/server/stream.h?cvsroot=gnash&r1=1.21&r2=1.22 http://cvs.savannah.gnu.org/viewcvs/gnash/server/styles.cpp?cvsroot=gnash&r1=1.31&r2=1.32 http://cvs.savannah.gnu.org/viewcvs/gnash/server/styles.h?cvsroot=gnash&r1=1.19&r2=1.20 http://cvs.savannah.gnu.org/viewcvs/gnash/server/types.cpp?cvsroot=gnash&r1=1.24&r2=1.25 http://cvs.savannah.gnu.org/viewcvs/gnash/server/types.h?cvsroot=gnash&r1=1.16&r2=1.17 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/action_buffer.cpp?cvsroot=gnash&r1=1.21&r2=1.22 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/morph2_character_def.cpp?cvsroot=gnash&r1=1.11&r2=1.12 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/morph2_character_def.h?cvsroot=gnash&r1=1.3&r2=1.4 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/shape_character_def.cpp?cvsroot=gnash&r1=1.31&r2=1.32 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.3960 retrieving revision 1.3961 diff -u -b -r1.3960 -r1.3961 --- ChangeLog 7 Aug 2007 16:27:36 -0000 1.3960 +++ ChangeLog 7 Aug 2007 20:53:09 -0000 1.3961 @@ -1,3 +1,29 @@ +2007-08-07 Sandro Santilli <[EMAIL PROTECTED]> + + * server/sprite_instance.cpp (processCompletedLoadVariableRequest): + fix attempt to increment past-the-end iterator. + * libbase/zlib_adaptar.cpp: don't hang on corrupted input. + * libbase/jpeg.{cpp,h}: don't segfault on corrupted input. + * server/matrix.cpp (read): add TODO item (check input) + * server/rect.cpp (read): add TODO item (check input) + * server/movie_instance.cpp (advance): warn only once about movie + containing no frames. + * server/parser/morph2_character_def.{cpp,h} (read): document, + don't read past end of tag. + * server/stream.h (read_variable_count): document and add + integrity checks. Add a GNASH_TRUST_SWF macro to turn ensureBytes + to a no-op. + * server/parser/shape_character_def.cpp (read_fill_styles, + read_line_styles, read): don't read past end of tag. Don't try to + recover if an exception is thrown by fill style parser. + * server/styles.{cpp,h} (line_style::read): don't read past end of tag. + * server/fill_style.{cpp,h} (read): don't read past end of tag. + * server/types.{cpp,h} (rgba::read_rgba, rgbe::read): don't read past end + of tag. + * server/parser/action_buffer.cpp (read): don't read past end of tag. + * Makefile.am: don't list 'doc' twice in subdirs. Fixes 'distclean' + rule. + 2007-08-07 Sergio Costas <raster (at) rastersoft.com> * backend/sound_handler_gst.cpp: Fix returns from getPosition Index: Makefile.am =================================================================== RCS file: /sources/gnash/gnash/Makefile.am,v retrieving revision 1.86 retrieving revision 1.87 diff -u -b -r1.86 -r1.87 --- Makefile.am 3 Aug 2007 19:27:29 -0000 1.86 +++ Makefile.am 7 Aug 2007 20:53:09 -0000 1.87 @@ -15,7 +15,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -# $Id: Makefile.am,v 1.86 2007/08/03 19:27:29 strk Exp $ +# $Id: Makefile.am,v 1.87 2007/08/07 20:53:09 strk Exp $ ## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = 1.6.0 @@ -34,7 +34,6 @@ plugin \ testsuite \ po \ - doc \ $(NULL) if CYGNAL Index: libbase/jpeg.cpp =================================================================== RCS file: /sources/gnash/gnash/libbase/jpeg.cpp,v retrieving revision 1.16 retrieving revision 1.17 diff -u -b -r1.16 -r1.17 --- libbase/jpeg.cpp 15 May 2007 13:26:47 -0000 1.16 +++ libbase/jpeg.cpp 7 Aug 2007 20:53:09 -0000 1.17 @@ -11,6 +11,7 @@ #include "jpeg.h" #include "tu_file.h" #include "log.h" +#include "GnashException.h" #include <cstdio> @@ -270,12 +271,7 @@ // Called when jpeglib has a fatal error. - static void jpeg_error_exit(j_common_ptr cinfo) - { - gnash::log_swferror("Internal jpeg error: %s", cinfo->err->jpeg_message_table[cinfo->err->msg_code]); - // TODO: set a flag to stop parsing !! - } - + static void jpeg_error_exit(j_common_ptr cinfo); // Set up some error handlers for the jpeg lib. static void setup_jpeg_err(jpeg_error_mgr* jerr) @@ -302,6 +298,11 @@ bool m_compressor_opened; + /// This flag will be set to true by the error callback + /// invoked by jpeg lib. Will be later used to throw + /// a ParserException. + /// + bool errorOccurred; enum SWF_DEFINE_BITS_JPEG2 { SWF_JPEG2 }; enum SWF_DEFINE_BITS_JPEG2_HEADER_ONLY { SWF_JPEG2_HEADER_ONLY }; @@ -310,10 +311,12 @@ // prepare to read data. input_impl(tu_file* in) : - m_compressor_opened(false) + m_compressor_opened(false), + errorOccurred(false) { setup_jpeg_err(&m_jerr); m_cinfo.err = &m_jerr; + m_cinfo.client_data = this; // Initialize decompression object. jpeg_create_decompress(&m_cinfo); @@ -333,10 +336,12 @@ // input_impl(SWF_DEFINE_BITS_JPEG2_HEADER_ONLY /* e */, tu_file* in) : - m_compressor_opened(false) + m_compressor_opened(false), + errorOccurred(false) { setup_jpeg_err(&m_jerr); m_cinfo.err = &m_jerr; + m_cinfo.client_data = this; // Initialize decompression object. jpeg_create_decompress(&m_cinfo); @@ -393,10 +398,37 @@ static const int stateReady = 202; /* found SOS, ready for start_decompress */ while (m_cinfo.global_state != stateReady) { - jpeg_read_header(&m_cinfo, FALSE); + int ret = jpeg_read_header(&m_cinfo, FALSE); + switch (ret) + { + case JPEG_SUSPENDED: // suspended due to lack of data + throw gnash::ParserException("lack of data during JPEG header parsing"); + //log_debug("jpeg_read_header returned JPEG_SUSPENDED"); + break; + case JPEG_HEADER_OK: // Found valid image datastream + //log_debug("jpeg_read_header returned JPEG_HEADER_OK"); + break; + case JPEG_HEADER_TABLES_ONLY: // Found valid table-specs-only datastream + //log_debug("jpeg_read_header returned JPEG_HEADER_TABLES_ONLY"); + break; + default: + //log_debug("jpeg_read_header returned %d", ret); + break; + } + } + + if ( errorOccurred ) + { + throw gnash::ParserException("errors during JPEG header parsing"); } jpeg_start_decompress(&m_cinfo); + + if ( errorOccurred ) + { + throw gnash::ParserException("errors during JPEG decompression"); + } + m_compressor_opened = true; } @@ -461,6 +493,16 @@ } }; + static void jpeg_error_exit(j_common_ptr cinfo) + { + gnash::log_swferror("Internal jpeg error: %s", cinfo->err->jpeg_message_table[cinfo->err->msg_code]); + + // Set a flag to stop parsing + input_impl* impl = static_cast<input_impl*>(cinfo->client_data); + impl->errorOccurred = true; + } + + /*static*/ input* Index: libbase/zlib_adapter.cpp =================================================================== RCS file: /sources/gnash/gnash/libbase/zlib_adapter.cpp,v retrieving revision 1.16 retrieving revision 1.17 diff -u -b -r1.16 -r1.17 --- libbase/zlib_adapter.cpp 24 May 2007 23:29:36 -0000 1.16 +++ libbase/zlib_adapter.cpp 7 Aug 2007 20:53:09 -0000 1.17 @@ -11,6 +11,7 @@ #include "tu_file.h" #include "utility.h" #include "log.h" +#include "GnashException.h" #include <memory> @@ -121,6 +122,8 @@ int inflate_from_stream(void* dst, int bytes) { + using gnash::ParserException; + if (m_error) { return 0; @@ -160,11 +163,23 @@ //m_error = 1; break; } + if (err == Z_DATA_ERROR) + { + throw ParserException("Data error inflating input"); + break; + } + if (err == Z_MEM_ERROR) + { + throw ParserException("Memory error inflating input"); + break; + } if (err != Z_OK) { // something's wrong. - gnash::log_error("inflater_impl::inflate_from_stream() inflate() returned %d", err); - m_error = 1; + std::stringstream ss; + ss << "inflater_impl::inflate_from_stream() inflate() returned " << err; + throw ParserException(ss.str()); + //m_error = 1; break; } @@ -174,6 +189,11 @@ } } + if (m_error) + { + return 0; + } + int bytes_read = bytes - m_zstream.avail_out; m_logical_stream_pos += bytes_read; @@ -267,6 +287,7 @@ int inflate_seek_to_end(void* appdata) { + GNASH_REPORT_FUNCTION; inflater_impl* inf = (inflater_impl*) appdata; if (inf->m_error) { Index: server/fill_style.cpp =================================================================== RCS file: /sources/gnash/gnash/server/fill_style.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -u -b -r1.6 -r1.7 --- server/fill_style.cpp 1 Jul 2007 10:54:22 -0000 1.6 +++ server/fill_style.cpp 7 Aug 2007 20:53:10 -0000 1.7 @@ -44,6 +44,7 @@ void gradient_record::read(stream* in, int tag_type) { + in->ensureBytes(1); m_ratio = in->read_u8(); m_color.read(in, tag_type); } @@ -72,6 +73,7 @@ void fill_style::read(stream* in, int tag_type, movie_definition* md) { + in->ensureBytes(1); m_type = in->read_u8(); IF_VERBOSE_PARSE @@ -126,6 +128,7 @@ m_gradient_matrix.concatenate(m); // GRADIENT + in->ensureBytes(1); uint8_t num_gradients = in->read_u8(); if ( ! num_gradients ) { @@ -174,6 +177,7 @@ // 0x42: tiled bitmap fill with hard edges // 0x43: clipped bitmap fill with hard edges + in->ensureBytes(2); int bitmap_char_id = in->read_u16(); IF_VERBOSE_PARSE ( @@ -214,10 +218,12 @@ } else { - log_unimpl("Unsupported fill style type: 0x%X", m_type); + stringstream ss; + ss << "Unknown fill style type " << m_type; + //log_unimpl("Unsupported fill style type: 0x%X", m_type); // This is a fatal error, we'll be leaving the stream // read pointer in an unknown position. - throw ParserException("Unsupported fill style (Malformed SWF?)"); + throw ParserException(ss.str()); // "Unsupported fill style (Malformed SWF?)"); } } Index: server/fill_style.h =================================================================== RCS file: /sources/gnash/gnash/server/fill_style.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -b -r1.7 -r1.8 --- server/fill_style.h 1 Jul 2007 10:54:22 -0000 1.7 +++ server/fill_style.h 7 Aug 2007 20:53:10 -0000 1.8 @@ -17,7 +17,7 @@ // Based on work of Thatcher Ulrich <[EMAIL PROTECTED]> 2003 -/* $Id: fill_style.h,v 1.7 2007/07/01 10:54:22 bjacques Exp $ */ +/* $Id: fill_style.h,v 1.8 2007/08/07 20:53:10 strk Exp $ */ #ifndef GNASH_FILL_STYLE_H #define GNASH_FILL_STYLE_H @@ -71,6 +71,9 @@ // /// TODO: use a subclass for this (swf_fill_style?) /// + /// Throw a ParserException if there's no enough bytes in the + /// currently opened tag for reading. See stream::ensureBytes() + /// void read(stream* in, int tag_type, movie_definition* m); /// \brief Index: server/matrix.cpp =================================================================== RCS file: /sources/gnash/gnash/server/matrix.cpp,v retrieving revision 1.16 retrieving revision 1.17 diff -u -b -r1.16 -r1.17 --- server/matrix.cpp 1 Jul 2007 10:54:23 -0000 1.16 +++ server/matrix.cpp 7 Aug 2007 20:53:10 -0000 1.17 @@ -19,7 +19,7 @@ // // Original author: Thatcher Ulrich <[EMAIL PROTECTED]> 2003 // -// $Id: matrix.cpp,v 1.16 2007/07/01 10:54:23 bjacques Exp $ +// $Id: matrix.cpp,v 1.17 2007/08/07 20:53:10 strk Exp $ // #ifdef HAVE_CONFIG_H @@ -206,6 +206,9 @@ matrix::read(stream* in) // Initialize from the stream. { + // TODO: compute number of bytes needed to read the matrix + // and ensure their availability using stream::ensureBytes + in->align(); set_identity(); Index: server/movie_instance.cpp =================================================================== RCS file: /sources/gnash/gnash/server/movie_instance.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -u -b -r1.14 -r1.15 --- server/movie_instance.cpp 1 Jul 2007 10:54:23 -0000 1.14 +++ server/movie_instance.cpp 7 Aug 2007 20:53:10 -0000 1.15 @@ -75,7 +75,11 @@ if ( get_frame_count() == 0 ) { IF_VERBOSE_MALFORMED_SWF( - log_swferror("The movie contains NO frames!"); + static bool warned=false; + if ( ! warned ) { + log_swferror(_("The movie with url %s has NO frames!"), m_def->get_url().c_str()); + warned=true; + } ); return; } Index: server/rect.cpp =================================================================== RCS file: /sources/gnash/gnash/server/rect.cpp,v retrieving revision 1.12 retrieving revision 1.13 diff -u -b -r1.12 -r1.13 --- server/rect.cpp 1 Jul 2007 10:54:24 -0000 1.12 +++ server/rect.cpp 7 Aug 2007 20:53:10 -0000 1.13 @@ -30,6 +30,11 @@ void rect::read(stream* in) { + // TODO: find how many bytes are required to + // read the whole rect and ensure they + // are available in the current tag + // using in->ensureBytes(x) + // in->align(); int nbits = in->read_uint(5); float xmin = (float) in->read_sint(nbits); Index: server/sprite_instance.cpp =================================================================== RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v retrieving revision 1.303 retrieving revision 1.304 diff -u -b -r1.303 -r1.304 --- server/sprite_instance.cpp 2 Aug 2007 21:23:42 -0000 1.303 +++ server/sprite_instance.cpp 7 Aug 2007 20:53:10 -0000 1.304 @@ -3851,7 +3851,7 @@ if ( _loadVariableRequests.empty() ) return; for (LoadVariablesThreads::iterator it=_loadVariableRequests.begin(); - it != _loadVariableRequests.end(); ++it) + it != _loadVariableRequests.end(); ) { LoadVariablesThread& request = *(*it); if ( request.completed() ) @@ -3859,6 +3859,10 @@ processCompletedLoadVariableRequest(request); it = _loadVariableRequests.erase(it); } + else + { + ++it; + } } } Index: server/stream.h =================================================================== RCS file: /sources/gnash/gnash/server/stream.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -b -r1.21 -r1.22 --- server/stream.h 1 Aug 2007 20:28:00 -0000 1.21 +++ server/stream.h 7 Aug 2007 20:53:10 -0000 1.22 @@ -16,6 +16,17 @@ #include <string> +// Define the following macro if you want to want Gnash parser +// to assume the underlying SWF is well-formed. It would make +// parsing faster, but might result in horrible behaviour with +// malformed SWFs (like taking up all system memory, keeping +// CPU busy for a long long time, or simply corrupting memory) +// +// This might be eventually set by a --disable-swf-checks or similar +// configure switch... +// +//#define GNASH_TRUST_SWF_INPUT + class tu_file; namespace gnash { @@ -49,11 +60,24 @@ int16_t read_s16(); uint32_t read_u32(); int32_t read_s32(); + + /// \brief + /// Read a length in a byte or three. + // + /// If the byte == 0xff, read the lenght in + /// next two bytes. + // + /// Takes care of integrity check (ensureByte) + /// unsigned read_variable_count() { + ensureBytes(1); unsigned count = read_u8(); if (count == 0xFF) + { + ensureBytes(2); count = read_u16(); + } return count; }; @@ -165,12 +189,16 @@ /// This method should be called before any attempt to read /// fields from the SWF. /// + /// NOTE: if GNASH_TRUST_SWF_INPUT is defined this function is a no-op + /// void ensureBytes(unsigned long needed) { +#ifndef GNASH_TRUST_SWF_INPUT if ( get_tag_end_position() - get_position() < needed ) { throw ParserException("premature end of tag"); } +#endif } private: Index: server/styles.cpp =================================================================== RCS file: /sources/gnash/gnash/server/styles.cpp,v retrieving revision 1.31 retrieving revision 1.32 diff -u -b -r1.31 -r1.32 --- server/styles.cpp 13 Feb 2007 15:19:32 -0000 1.31 +++ server/styles.cpp 7 Aug 2007 20:53:10 -0000 1.32 @@ -33,6 +33,7 @@ void line_style::read(stream* in, int tag_type) { + in->ensureBytes(2); m_width = in->read_u16(); m_color.read(in, tag_type); } Index: server/styles.h =================================================================== RCS file: /sources/gnash/gnash/server/styles.h,v retrieving revision 1.19 retrieving revision 1.20 diff -u -b -r1.19 -r1.20 --- server/styles.h 14 Feb 2007 01:40:27 -0000 1.19 +++ server/styles.h 7 Aug 2007 20:53:10 -0000 1.20 @@ -5,7 +5,7 @@ // line style types. -/* $Id: styles.h,v 1.19 2007/02/14 01:40:27 strk Exp $ */ +/* $Id: styles.h,v 1.20 2007/08/07 20:53:10 strk Exp $ */ #ifndef GNASH_STYLES_H #define GNASH_STYLES_H @@ -54,6 +54,9 @@ /// Stream is assumed to be positioned at /// the right place. /// + /// Throw a ParserException if there's no enough bytes in the + /// currently opened tag for reading. See stream::ensureBytes() + /// void read(stream* in, int tag_type); /// Return thickness of the line, in TWIPS Index: server/types.cpp =================================================================== RCS file: /sources/gnash/gnash/server/types.cpp,v retrieving revision 1.24 retrieving revision 1.25 diff -u -b -r1.24 -r1.25 --- server/types.cpp 23 Apr 2007 19:19:30 -0000 1.24 +++ server/types.cpp 7 Aug 2007 20:53:10 -0000 1.25 @@ -74,11 +74,13 @@ void rgba::read_rgba(stream* in) { read_rgb(in); + in->ensureBytes(1); m_a = in->read_u8(); } void rgba::read_rgb(stream* in) { + in->ensureBytes(3); m_r = in->read_u8(); m_g = in->read_u8(); m_b = in->read_u8(); Index: server/types.h =================================================================== RCS file: /sources/gnash/gnash/server/types.h,v retrieving revision 1.16 retrieving revision 1.17 diff -u -b -r1.16 -r1.17 --- server/types.h 22 Jul 2007 03:29:25 -0000 1.16 +++ server/types.h 7 Aug 2007 20:53:10 -0000 1.17 @@ -96,9 +96,16 @@ /// a value <= 22 makes it read RGB /// and value > 22 makes it read RGBA /// + /// Throw a ParserException if there's no enough bytes in the + /// currently opened tag for reading. See stream::ensureBytes() + /// void read(stream* in, int tag_type); /// Initialize from intput stream (reads RGBA) + // + /// Throw a ParserException if there's no enough bytes in the + /// currently opened tag for reading. See stream::ensureBytes() + /// void read_rgba(stream* in); /// Initialize from intput stream (reads RGB) Index: server/parser/action_buffer.cpp =================================================================== RCS file: /sources/gnash/gnash/server/parser/action_buffer.cpp,v retrieving revision 1.21 retrieving revision 1.22 diff -u -b -r1.21 -r1.22 --- server/parser/action_buffer.cpp 1 Jul 2007 10:54:33 -0000 1.21 +++ server/parser/action_buffer.cpp 7 Aug 2007 20:53:10 -0000 1.22 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: action_buffer.cpp,v 1.21 2007/07/01 10:54:33 bjacques Exp $ */ +/* $Id: action_buffer.cpp,v 1.22 2007/08/07 20:53:10 strk Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -66,16 +66,19 @@ size_t pc = m_buffer.size(); #endif + in->ensureBytes(1); // action_id uint8_t action_id = in->read_u8(); m_buffer.push_back(action_id); if (action_id & 0x80) { // Action contains extra data. Read it. + in->ensureBytes(2); // action length uint16_t length = in->read_u16(); m_buffer.push_back(length & 0x0FF); m_buffer.push_back((length >> 8) & 0x0FF); + in->ensureBytes(length); // action actions for (uint16_t i = 0; i < length; i++) { - uint8_t b = in->read_u8(); + uint8_t b = in->read_u8(); // bytes ensured outside loop m_buffer.push_back(b); } } Index: server/parser/morph2_character_def.cpp =================================================================== RCS file: /sources/gnash/gnash/server/parser/morph2_character_def.cpp,v retrieving revision 1.11 retrieving revision 1.12 diff -u -b -r1.11 -r1.12 --- server/parser/morph2_character_def.cpp 1 Jul 2007 10:54:34 -0000 1.11 +++ server/parser/morph2_character_def.cpp 7 Aug 2007 20:53:10 -0000 1.12 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: morph2_character_def.cpp,v 1.11 2007/07/01 10:54:34 bjacques Exp $ */ +/* $Id: morph2_character_def.cpp,v 1.12 2007/08/07 20:53:10 strk Exp $ */ // Based on the public domain morph2.cpp of: // Thatcher Ulrich <[EMAIL PROTECTED]>, Mike Shaver <[EMAIL PROTECTED]> 2003, @@ -227,13 +227,16 @@ m_shape1->set_bound(bound1); m_shape2->set_bound(bound2); + in->ensureBytes(4); offset = in->read_u32(); + // Next line will throw ParserException on malformed SWF fill_style_count = in->read_variable_count(); int i; for (i = 0; i < fill_style_count; i++) { fill_style fs1, fs2; + in->ensureBytes(1); fs1.m_type = in->read_u8(); fs2.m_type = fs1.m_type; @@ -285,6 +288,7 @@ fs2.m_gradient_matrix.concatenate(m2); // GRADIENT + in->ensureBytes(1); int num_gradients = in->read_u8(); assert(num_gradients >= 1 && num_gradients <= 8); @@ -312,6 +316,7 @@ else if (fs1.m_type == 0x40 || fs1.m_type == 0x41) { + in->ensureBytes(2); int bitmap_char_id = in->read_u16(); IF_VERBOSE_PARSE( log_parse(_("morph fsr bitmap_char = %d"), @@ -338,6 +343,7 @@ line_style_count = in->read_variable_count(); for (i = 0; i < line_style_count; i++) { line_style ls1, ls2; + in->ensureBytes(4); ls1.m_width = in->read_u16(); ls2.m_width = in->read_u16(); ls1.m_color.read(in, tag_type); Index: server/parser/morph2_character_def.h =================================================================== RCS file: /sources/gnash/gnash/server/parser/morph2_character_def.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -b -r1.3 -r1.4 --- server/parser/morph2_character_def.h 16 Jun 2007 10:40:57 -0000 1.3 +++ server/parser/morph2_character_def.h 7 Aug 2007 20:53:10 -0000 1.4 @@ -19,7 +19,30 @@ public: morph2_character_def(); virtual ~morph2_character_def(); + + /// Read a DefineMorphShape tag from stream + // + /// Throw ParserException if the tag is malformed + /// + /// @param in + /// The stream to read the definition from. + /// Tag type is assumed to have been read already + /// + /// @param tag_type + /// Type of the tag. + /// Need be SWF::DEFINEMORPHSHAPE or an assertion would fail. + /// TODO: drop ? + /// + /// @param with_style + /// Unused. TODO: drop. + /// + /// @param md + /// Movie definition. Used to resolv character ids for fill styles. + /// Must be not-null or would segfault. + /// TODO: take by reference ! + /// void read(stream* in, int tag_type, bool with_style, movie_definition* m); + virtual void display(character* inst); void lerp_matrix(matrix& t, const matrix& m1, const matrix& m2, const float ratio); Index: server/parser/shape_character_def.cpp =================================================================== RCS file: /sources/gnash/gnash/server/parser/shape_character_def.cpp,v retrieving revision 1.31 retrieving revision 1.32 diff -u -b -r1.31 -r1.32 --- server/parser/shape_character_def.cpp 6 Aug 2007 03:30:19 -0000 1.31 +++ server/parser/shape_character_def.cpp 7 Aug 2007 20:53:10 -0000 1.32 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: shape_character_def.cpp,v 1.31 2007/08/06 03:30:19 strk Exp $ */ +/* $Id: shape_character_def.cpp,v 1.32 2007/08/07 20:53:10 strk Exp $ */ // Based on the public domain shape.cpp of Thatcher Ulrich <[EMAIL PROTECTED]> 2003 @@ -30,7 +30,6 @@ #include "render.h" #include "stream.h" #include "sprite_instance.h" -#include "GnashException.h" #include "tu_file.h" @@ -72,11 +71,13 @@ { // Get the count. + in->ensureBytes(1); uint16_t fill_style_count = in->read_u8(); if (tag_type > 2) { if (fill_style_count == 0xFF) { + in->ensureBytes(2); fill_style_count = in->read_u16(); } } @@ -92,16 +93,7 @@ // TODO: add a fill_style constructor directly // reading from stream fill_style fs; - try - { fs.read(in, tag_type, m); - } - catch (ParserException& e) - { - IF_VERBOSE_MALFORMED_SWF( - log_swferror("%s", e.what()); - ); - } // Push a style anyway, so any path referring to // it still finds it.. styles.push_back(fs); @@ -115,6 +107,7 @@ // Read line styles and push them onto the back of the given array. { // Get the count. + in->ensureBytes(1); int line_style_count = in->read_u8(); IF_VERBOSE_PARSE @@ -126,6 +119,7 @@ // if (tag_type > 2) // { if (line_style_count == 0xFF) { + in->ensureBytes(2); line_style_count = in->read_u16(); IF_VERBOSE_PARSE ( _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit