gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog server/parser/button_character_...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/parser/button_character_...
Date: Wed, 12 Dec 2007 23:49:28 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/12/12 23:49:28

Modified files:
        .              : ChangeLog 
        server/parser  : button_character_def.cpp button_character_def.h 

Log message:
        cleanup parser by splitting DEFINEBUTTON, DEFINEBUTTON2 and 
DEFINEBUTTONSOUND
        reading functions. Added a boundary arg to button_record parser to 
avoid reading
        out of bounds (with side-effect of reducing seek-back need)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5151&r2=1.5152
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/button_character_def.cpp?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/button_character_def.h?cvsroot=gnash&r1=1.20&r2=1.21

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5151
retrieving revision 1.5152
diff -u -b -r1.5151 -r1.5152
--- ChangeLog   12 Dec 2007 22:45:27 -0000      1.5151
+++ ChangeLog   12 Dec 2007 23:49:27 -0000      1.5152
@@ -1,5 +1,13 @@
 2007-12-12 Sandro Santilli <address@hidden>
 
+       * server/parser/button_character_def.{cpp,h}: cleanup parser by 
+         splitting DEFINEBUTTON, DEFINEBUTTON2 and DEFINEBUTTONSOUND
+         reading functions. Added a boundary arg to button_record parser
+         to avoid reading out of bounds (with side-effect of reducing
+         seek-back need)
+
+2007-12-12 Sandro Santilli <address@hidden>
+
        * testsuite/actionscript.all/System.as: update expected results.
        * server/swf/tag_loaders.cpp (define_bits_jpeg3_loader): don't read
          rgb data past alpha_position.

Index: server/parser/button_character_def.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/button_character_def.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/parser/button_character_def.cpp      7 Oct 2007 21:15:59 -0000       
1.19
+++ server/parser/button_character_def.cpp      12 Dec 2007 23:49:28 -0000      
1.20
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: button_character_def.cpp,v 1.19 2007/10/07 21:15:59 strk Exp $ */
+/* $Id: button_character_def.cpp,v 1.20 2007/12/12 23:49:28 strk Exp $ */
 
 // Based on the public domain work of Thatcher Ulrich <address@hidden> 2003
 
@@ -91,18 +91,34 @@
 
 bool
 button_record::read(stream* in, int tag_type,
-               movie_definition* m)
+               movie_definition* m, unsigned long endPos)
 {
+       // caller should check this
+       assert(in->get_position() < endPos);
        int     flags = in->read_u8();
        if (flags == 0)
        {
                return false;
        }
-       m_hit_test = flags & 8 ? true : false;
-       m_down = flags & 4 ? true : false;
-       m_over = flags & 2 ? true : false;
-       m_up = flags & 1 ? true : false;
 
+       // Upper 4 bits are:
+       //
+       //   ButtonReserved = readBits (f, 2);
+       //   ButtonHasBlendMode = readBits(f, 1);
+       //   ButtonHasFilterList = readBits(f, 1);
+       //
+       m_hit_test = flags & (1<<3); // 8 ? true : false;
+       m_down     = flags & (1<<2); // 4 ? true : false;
+       m_over     = flags & (1<<1); // 2 ? true : false;
+       m_up       = flags & (1<<0); // 1 ? true : false;
+
+       if (in->get_position()+2 > endPos)
+       {
+               IF_VERBOSE_MALFORMED_SWF(
+               log_swferror(_("   premature end of button record input stream, 
can't read character id"));
+               );
+               return false;
+       }
        m_character_id = in->read_u16();
 
        // Get character definition now (safer)
@@ -122,16 +138,26 @@
        {
                IF_VERBOSE_PARSE(
                log_parse(_("   button record for states %x contain "
-                       "character %d (%s)"), flags, m_character_id,
+                       "character %d (%s)"), 
(m_hit_test<<4)+(m_down<<2)+(m_over<<1)+(m_up), m_character_id,
                        typeName(*m_character_def).c_str());
                );
        }
 
+       if (in->get_position()+2 > endPos)
+       {
+               IF_VERBOSE_MALFORMED_SWF(
+               log_swferror(_("   premature end of button record input stream, 
can't read button layer (depth?)"));
+               );
+               return false;
+       }
        m_button_layer = in->read_u16();
+
+       // TODO: pass available range to button matrix read
        m_button_matrix.read(in);
 
-       if (tag_type == 34)
+       if (tag_type == SWF::DEFINEBUTTON2)
        {
+               // TODO: pass available range to button cxform read
                m_button_cxform.read_rgba(in);
        }
 
@@ -202,29 +228,20 @@
        );
 }
 
-
-
 void
-button_character_definition::read(stream* in, int tag_type, movie_definition* 
m)
-// Initialize from the given stream.
+button_character_definition::readDefineButton(stream* in, movie_definition* m)
 {
        // Character ID has been read already
 
-       assert(
-               tag_type == SWF::DEFINEBUTTON           // 7
-               || tag_type == SWF::DEFINEBUTTONSOUND   // 17
-               || tag_type == SWF::DEFINEBUTTON2       // 34
-        );
-
-       if (tag_type == SWF::DEFINEBUTTON)
-       {
                // Old button tag.
 
+       unsigned long endTagPos = in->get_tag_end_position();
+
                // Read button character records.
                for (;;)
                {
                        button_record   r;
-                       if (r.read(in, tag_type, m) == false)
+               if (r.read(in, SWF::DEFINEBUTTON, m, endTagPos) == false)
                        {
                                // Null record; marks the end of button records.
                                break;
@@ -238,50 +255,64 @@
                        }
                }
 
+       if ( in->get_position() >= endTagPos )
+       {
+               IF_VERBOSE_MALFORMED_SWF(
+               log_swferror(_("Premature end of DEFINEBUTTON tag, won't read 
actions"));
+               );
+               return;
+       }
+
                // Read actions.
                button_action actions;
-               actions.read(in, tag_type);
+       // TODO: pass valid end position to button_action parser
+       actions.read(in, SWF::DEFINEBUTTON);
                m_button_actions.push_back(actions);
-       }
-       else if (tag_type == SWF::DEFINEBUTTONSOUND)
-       {
-               assert(m_sound == NULL);        // redefinition button sound is 
error
-               m_sound = new button_sound_def();
-               IF_VERBOSE_PARSE(
-               log_parse(_("button sound options: "));
-               );
-               for (int i = 0; i < 4; i++)
-               {
-                       button_sound_info& bs = m_sound->m_button_sounds[i];
-                       bs.m_sound_id = in->read_u16();
-                       if (bs.m_sound_id > 0)
-                       {
-                               bs.m_sam = m->get_sound_sample(bs.m_sound_id);
-                               if (bs.m_sam == NULL)
+
+       // detect min/max layer number
+       m_min_layer=0;
+       m_max_layer=0;
+       for (unsigned int i=0; i<m_button_records.size(); i++)
                                {
-//                                             printf("sound tag not found, 
sound_id=%d, button state #=%i", bs.sound_id, i);
-                               }
-                               IF_VERBOSE_PARSE(
-                               log_parse("\n   sound_id = %d", bs.m_sound_id);
-                               );
-                               bs.m_sound_style.read(in);
-                       }
-               }
+         int this_layer = m_button_records[i].m_button_layer;
+
+         if ((i==0) || (this_layer < m_min_layer))  m_min_layer=this_layer;
+         if ((i==0) || (this_layer > m_max_layer))  m_max_layer=this_layer;
        }
-       else if (tag_type == SWF::DEFINEBUTTON2)
-       {
+}
+
+void
+button_character_definition::readDefineButton2(stream* in, movie_definition* m)
+{
+       // Character ID has been read already
+
                // Read the menu flag
                // (this is a single bit, the other 7 bits are reserved)
                m_menu = in->read_u8() != 0;
 
                unsigned button_2_action_offset = in->read_u16();
+       unsigned long tagEndPosition = in->get_tag_end_position();
                unsigned next_action_pos = in->get_position() + 
button_2_action_offset - 2;
 
+       if ( next_action_pos > tagEndPosition )
+       {
+               IF_VERBOSE_MALFORMED_SWF(
+               log_swferror(_("Next Button2 actionOffset (%u) points past the 
end of tag (%lu)"),
+                       button_2_action_offset, tagEndPosition);
+               );
+               return;
+       }
+
+       unsigned long endOfButtonRecords = tagEndPosition;
+       if ( ! button_2_action_offset  ) endOfButtonRecords = tagEndPosition;
+
                // Read button records.
-               for (;;)
+       // takes at least 1 byte for the end mark button record, so 
+       // we don't attempt to parse at all unless we have at least 1 byte left
+       while ( in->get_position() < endOfButtonRecords )
                {
                        button_record   r;
-                       if (r.read(in, tag_type, m) == false)
+               if (r.read(in, SWF::DEFINEBUTTON2, m, endOfButtonRecords) == 
false)
                        {
                                // Null record; marks the end of button records.
                                break;
@@ -295,24 +326,17 @@
                        }
                }
 
-               if ( next_action_pos >= in->get_tag_end_position() )
-               {
-                       IF_VERBOSE_MALFORMED_SWF(
-                       log_swferror(_("Next Button2 actionOffset (%u) points 
past the end of tag"), button_2_action_offset);
-                       );
-                       return;
-               }
-
                in->set_position(next_action_pos);
 
                // Read Button2ActionConditions
-               for (;;)
+       // Don't read past tag end
+       while ( in->get_position() < tagEndPosition ) 
                {
                        unsigned next_action_offset = in->read_u16();
                        next_action_pos = in->get_position() + 
next_action_offset - 2;
 
                        m_button_actions.resize(m_button_actions.size() + 1);
-                       m_button_actions.back().read(in, tag_type);
+               m_button_actions.back().read(in, SWF::DEFINEBUTTON2);
 
                        if (next_action_offset == 0 )
                        {
@@ -333,8 +357,6 @@
                        // seek to next action.
                        in->set_position(next_action_pos);
                }
-       }
-
 
        // detect min/max layer number
        m_min_layer=0;
@@ -348,6 +370,69 @@
   }
 }
 
+void
+button_character_definition::readDefineButtonSound(stream* in, 
movie_definition* m)
+{
+       // Character ID has been read already
+
+       if ( m_sound )
+       {
+               IF_VERBOSE_MALFORMED_SWF(
+               log_swferror(_("Attempt to redefine button sound ignored"));
+               );
+               return;
+       }
+
+       m_sound = new button_sound_def();
+
+       IF_VERBOSE_PARSE(
+       log_parse(_("button sound options: "));
+       );
+
+       for (int i = 0; i < 4; i++)
+       {
+               button_sound_info& bs = m_sound->m_button_sounds[i];
+               bs.m_sound_id = in->read_u16();
+               if (bs.m_sound_id)
+               {
+                       bs.m_sam = m->get_sound_sample(bs.m_sound_id);
+                       if ( ! bs.m_sam )
+                       {
+                               IF_VERBOSE_MALFORMED_SWF(
+                               log_swferror(_("sound tag not found, 
sound_id=%d, button state #=%i"), bs.m_sound_id, i);
+                               );
+                       }
+                       IF_VERBOSE_PARSE(
+                       log_parse("\n   sound_id = %d", bs.m_sound_id);
+                       );
+                       bs.m_sound_style.read(in);
+               }
+       }
+}
+
+
+void
+button_character_definition::read(stream* in, int tag_type, movie_definition* 
m)
+// Initialize from the given stream.
+{
+       // Character ID has been read already
+
+       switch (tag_type)
+       {
+               case SWF::DEFINEBUTTON:
+                       readDefineButton(in, m);
+                       break;
+               case SWF::DEFINEBUTTONSOUND:
+                       readDefineButtonSound(in, m);
+                       break;
+               case SWF::DEFINEBUTTON2:
+                       readDefineButton2(in, m);
+                       break;
+               default:
+                       abort();
+       }
+}
+
 
 character*
 button_character_definition::create_character_instance(

Index: server/parser/button_character_def.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/button_character_def.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- server/parser/button_character_def.h        4 Dec 2007 11:45:32 -0000       
1.20
+++ server/parser/button_character_def.h        12 Dec 2007 23:49:28 -0000      
1.21
@@ -56,7 +56,11 @@
        /// Read a button record from the SWF stream.
        //
        /// Return true if we read a record; false if this is a null
-       bool    read(stream* in, int tag_type, movie_definition* m);
+       ///
+       /// @param endPos
+       ///     Last stream offset available for a valid read
+       ///
+       bool    read(stream* in, int tag_type, movie_definition* m, unsigned 
long endPos);
 
        /// Return true if the button_record is valid
        //
@@ -96,6 +100,8 @@
        int     m_conditions;
 
        typedef std::vector<action_buffer*> ActionList;
+
+       // TODO: define ownership of list elements !!
        ActionList m_actions;
 
        ~button_action();
@@ -153,7 +159,9 @@
 
        struct button_sound_def
        {
-               void    read(stream* in, movie_definition* m);
+               // TODO: implement ?
+               //void  read(stream* in, movie_definition* m);
+
                button_sound_info m_button_sounds[4];
 
 #ifdef GNASH_USE_GC
@@ -181,6 +189,7 @@
        typedef std::vector<button_action> ButtonActVect;
        ButtonActVect m_button_actions;
 
+       // TODO: define ownership of this sound !
        button_sound_def*       m_sound;
 
        button_character_definition();
@@ -189,8 +198,18 @@
        /// Create a mutable instance of our definition.
        character* create_character_instance(character* parent, int id);
 
+       /// Read a SWF::DEFINEBUTTON, SWF::DEFINEBUTTONSOUND or 
SWF::DEFINEBUTTON2
        void    read(stream* in, int tag_type, movie_definition* m);
        
+       /// Read a SWF::DEFINEBUTTON tag
+       void    readDefineButton(stream* in, movie_definition* m);
+
+       /// Read a SWF::DEFINEBUTTON2 tag
+       void    readDefineButton2(stream* in, movie_definition* m);
+
+       /// Read a SWF::DEFINEBUTTONSOUND tag
+       void    readDefineButtonSound(stream* in, movie_definition* m);
+       
        const rect&     get_bound() const {
     // It is required that get_bound() is implemented in character definition
     // classes. However, button character definitions do not have shape 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]