CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 07/12/13 10:58:10
Modified files: . : ChangeLog server/parser : action_buffer.cpp action_buffer.h button_character_def.cpp button_character_def.h server/swf : DoActionTag.h DoInitActionTag.h PlaceObject2Tag.cpp Log message: Limit input stream reads while parsing action buffers. This fixes seek-backs while parsing button actions. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5159&r2=1.5160 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/action_buffer.cpp?cvsroot=gnash&r1=1.29&r2=1.30 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/action_buffer.h?cvsroot=gnash&r1=1.23&r2=1.24 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/button_character_def.cpp?cvsroot=gnash&r1=1.21&r2=1.22 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/button_character_def.h?cvsroot=gnash&r1=1.21&r2=1.22 http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/DoActionTag.h?cvsroot=gnash&r1=1.9&r2=1.10 http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/DoInitActionTag.h?cvsroot=gnash&r1=1.4&r2=1.5 http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/PlaceObject2Tag.cpp?cvsroot=gnash&r1=1.27&r2=1.28 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.5159 retrieving revision 1.5160 diff -u -b -r1.5159 -r1.5160 --- ChangeLog 13 Dec 2007 09:09:24 -0000 1.5159 +++ ChangeLog 13 Dec 2007 10:58:10 -0000 1.5160 @@ -1,3 +1,12 @@ +2007-12-13 Sandro Santilli <[EMAIL PROTECTED]> + + * server/parser/action_buffer.{cpp,h}: drop readFullTag(), + get additional arg to read() to limit input stream. + * server/parser/button_character_def.{cpp,h}: limit input + stream while reading button_actions. + * server/swf/: DoActionTag.h, DoInitActionTag.h, + PlaceObject2Tag.cpp: update calls to action_buffer parser. + 2007-12-13 Benjamin Wolsey <[EMAIL PROTECTED]> * server/asobj/Global.cpp: put return in updateAfterEvent(); Index: server/parser/action_buffer.cpp =================================================================== RCS file: /sources/gnash/gnash/server/parser/action_buffer.cpp,v retrieving revision 1.29 retrieving revision 1.30 diff -u -b -r1.29 -r1.30 --- server/parser/action_buffer.cpp 12 Dec 2007 10:23:46 -0000 1.29 +++ server/parser/action_buffer.cpp 13 Dec 2007 10:58:10 -0000 1.30 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: action_buffer.cpp,v 1.29 2007/12/12 10:23:46 zoulunkai Exp $ */ +/* $Id: action_buffer.cpp,v 1.30 2007/12/13 10:58:10 strk Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -56,10 +56,11 @@ } void -action_buffer::readFullTag(stream* in) +action_buffer::read(stream& in, unsigned long endPos) { - unsigned long endPos = in->get_tag_end_position(); - unsigned long startPos = in->get_position(); + unsigned long startPos = in.get_position(); + assert(endPos > startPos); // caller should check this + assert(endPos <= in.get_tag_end_position()); unsigned size = endPos-startPos; // Allocate the buffer @@ -80,7 +81,7 @@ // tag should give significant speedup in parsing // large action-based movies. // - in->read(reinterpret_cast<char*>(buf), size); + in.read(reinterpret_cast<char*>(buf), size); // Consistency checks here // @@ -96,48 +97,6 @@ ); } -void -action_buffer::read(stream* in) -{ - // NOTE: - // This method is called for tags like button actions, - // where we don't know the size of the action block in advance - // and are thus forced to seek for an END opcode. - // For DoAction and DoInitAction you can use the readFullTag method - // instead, which is faster. - - // Read action bytes. - unsigned long endPos = in->get_tag_end_position(); - while ( in->get_position() < endPos ) - { -#if 0 - size_t instruction_start = m_buffer.size(); - size_t pc = m_buffer.size(); -#endif - - boost::uint8_t action_id = in->read_u8(); - m_buffer.push_back(action_id); - - if (action_id & 0x80) { - // Action contains extra data. Read it. - boost::uint16_t length = in->read_u16(); - m_buffer.push_back(length & 0x0FF); - m_buffer.push_back((length >> 8) & 0x0FF); - for (boost::uint16_t i = 0; i < length; i++) { - boost::uint8_t b = in->read_u8(); // bytes ensured outside loop - m_buffer.push_back(b); - } - } - - if (action_id == SWF::ACTION_END) - { - // end of action buffer. - break; - } - } -} - - /*public*/ void action_buffer::process_decl_dict(size_t start_pc, size_t stop_pc) const Index: server/parser/action_buffer.h =================================================================== RCS file: /sources/gnash/gnash/server/parser/action_buffer.h,v retrieving revision 1.23 retrieving revision 1.24 diff -u -b -r1.23 -r1.24 --- server/parser/action_buffer.h 12 Dec 2007 10:23:46 -0000 1.23 +++ server/parser/action_buffer.h 13 Dec 2007 10:58:10 -0000 1.24 @@ -60,11 +60,15 @@ action_buffer(); - /// Read action bytes from input stream up to an SWF::ACTION_END or end of tag - void read(stream* in); - - /// Read action bytes from input stream up to end of tag - void readFullTag(stream* in); + /// Read action bytes from input stream up to but not including endPos + // + /// @param endPos + /// One past last valid-to-read byte position. + /// Make sure it's > then in.get_position() and + /// <= in.get_tag_end_position() or an assertion will + /// fail. + /// + void read(stream& in, unsigned long endPos); bool is_null() const { Index: server/parser/button_character_def.cpp =================================================================== RCS file: /sources/gnash/gnash/server/parser/button_character_def.cpp,v retrieving revision 1.21 retrieving revision 1.22 diff -u -b -r1.21 -r1.22 --- server/parser/button_character_def.cpp 13 Dec 2007 00:26:50 -0000 1.21 +++ server/parser/button_character_def.cpp 13 Dec 2007 10:58:10 -0000 1.22 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: button_character_def.cpp,v 1.21 2007/12/13 00:26:50 strk Exp $ */ +/* $Id: button_character_def.cpp,v 1.22 2007/12/13 10:58:10 strk Exp $ */ // Based on the public domain work of Thatcher Ulrich <[EMAIL PROTECTED]> 2003 @@ -56,7 +56,7 @@ m_actions.clear(); // this is useless, will be done automatically } -void button_action::read(stream* in, int tag_type) +void button_action::read(stream* in, int tag_type, unsigned long endPos) { // Read condition flags. if (tag_type == SWF::DEFINEBUTTON) // 7 @@ -66,6 +66,14 @@ else { assert(tag_type == SWF::DEFINEBUTTON2); // 34 + + if ( in->get_position()+2 > endPos ) + { + IF_VERBOSE_MALFORMED_SWF( + log_swferror(_("Premature end of button action input: can't read conditions")); + ); + return; + } m_conditions = in->read_u16(); } @@ -75,7 +83,7 @@ // Read actions. action_buffer* a = new action_buffer; - a->read(in); + a->read(*in, endPos); m_actions.push_back(a); } @@ -266,7 +274,7 @@ // Read actions. button_action actions; // TODO: pass valid end position to button_action parser - actions.read(in, SWF::DEFINEBUTTON); + actions.read(in, SWF::DEFINEBUTTON, endTagPos); m_button_actions.push_back(actions); // detect min/max layer number @@ -337,8 +345,10 @@ unsigned next_action_offset = in->read_u16(); next_action_pos = in->get_position() + next_action_offset - 2; + unsigned long endActionPos = next_action_offset ? next_action_pos : tagEndPosition; + m_button_actions.resize(m_button_actions.size() + 1); - m_button_actions.back().read(in, SWF::DEFINEBUTTON2); + m_button_actions.back().read(in, SWF::DEFINEBUTTON2, endActionPos); if (next_action_offset == 0 ) { Index: server/parser/button_character_def.h =================================================================== RCS file: /sources/gnash/gnash/server/parser/button_character_def.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -b -r1.21 -r1.22 --- server/parser/button_character_def.h 12 Dec 2007 23:49:28 -0000 1.21 +++ server/parser/button_character_def.h 13 Dec 2007 10:58:10 -0000 1.22 @@ -105,7 +105,11 @@ ActionList m_actions; ~button_action(); - void read(stream* in, int tag_type); + + /// @param endPos + /// One past last valid-to-read byte position + /// + void read(stream* in, int tag_type, unsigned long endPos); }; Index: server/swf/DoActionTag.h =================================================================== RCS file: /sources/gnash/gnash/server/swf/DoActionTag.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -b -r1.9 -r1.10 --- server/swf/DoActionTag.h 4 Dec 2007 11:45:33 -0000 1.9 +++ server/swf/DoActionTag.h 13 Dec 2007 10:58:10 -0000 1.10 @@ -30,10 +30,10 @@ #include "swf.h" // for tag_type definition #include "action_buffer.h" // for composition #include "sprite_instance.h" // for inlines +#include "stream.h" // for inlines // Forward declarations namespace gnash { - class stream; class movie_definition; } @@ -55,7 +55,7 @@ // void read(stream* in) { - m_buf.readFullTag(in); + m_buf.read(*in, in->get_tag_end_position()); } virtual void execute(sprite_instance* m) const Index: server/swf/DoInitActionTag.h =================================================================== RCS file: /sources/gnash/gnash/server/swf/DoInitActionTag.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -b -r1.4 -r1.5 --- server/swf/DoInitActionTag.h 4 Dec 2007 11:45:33 -0000 1.4 +++ server/swf/DoInitActionTag.h 13 Dec 2007 10:58:10 -0000 1.5 @@ -30,10 +30,10 @@ #include "swf.h" // for tag_type definition #include "action_buffer.h" // for composition #include "sprite_instance.h" // for inlines +#include "stream.h" // for inlines // Forward declarations namespace gnash { - class stream; class movie_definition; } @@ -55,7 +55,7 @@ // void read(stream* in) { - m_buf.readFullTag(in); + m_buf.read(*in, in->get_tag_end_position()); } virtual void execute_state(sprite_instance* m) const Index: server/swf/PlaceObject2Tag.cpp =================================================================== RCS file: /sources/gnash/gnash/server/swf/PlaceObject2Tag.cpp,v retrieving revision 1.27 retrieving revision 1.28 diff -u -b -r1.27 -r1.28 --- server/swf/PlaceObject2Tag.cpp 12 Dec 2007 10:23:47 -0000 1.27 +++ server/swf/PlaceObject2Tag.cpp 13 Dec 2007 10:58:10 -0000 1.28 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: PlaceObject2Tag.cpp,v 1.27 2007/12/12 10:23:47 zoulunkai Exp $ */ +/* $Id: PlaceObject2Tag.cpp,v 1.28 2007/12/13 10:58:10 strk Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -119,41 +119,9 @@ // Read the actions for event(s) action_buffer* action = new action_buffer(); _actionBuffers.push_back(action); // take ownership - action->read(in); + action->read(*in, in->get_position()+event_length); - size_t readlen = action->size(); - if (readlen > event_length) - { - IF_VERBOSE_MALFORMED_SWF( - log_swferror(_("swf_event::read(), " - "event_length = %d, " - "but read " SIZET_FMT - ". Breaking for safety."), - event_length, readlen); - ); - // or should we just continue here ? - break; - } - else if ( readlen < event_length ) - { - IF_VERBOSE_MALFORMED_SWF( - log_swferror(_("swf_event::read(), " - "event_length = %d, " - "but read " SIZET_FMT - ". Skipping excessive bytes."), - event_length, readlen); - ); - - if ( ! in->skip_bytes(event_length - readlen) ) - { - // TODO: should we throw a ParserException instead - // so to completely discard this tag ? - IF_VERBOSE_MALFORMED_SWF( - log_swferror(_("Bytes skipping failed.")); - ); - break; - } - } + assert(action->size() == event_length); // 13 bits reserved, 19 bits used const int total_known_events = 19; _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit