gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog libbase/tu_file.h server/impl.c...


From: Chad Musick
Subject: [Gnash-commit] gnash ChangeLog libbase/tu_file.h server/impl.c...
Date: Fri, 21 Sep 2007 13:40:32 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Chad Musick <cmusick>   07/09/21 13:40:32

Modified files:
        .              : ChangeLog 
        libbase        : tu_file.h 
        server         : impl.cpp stream.cpp stream.h 
        server/parser  : Makefile.am abc_block.cpp abc_block.h 
        server/swf     : tag_loaders.cpp tag_loaders.h 

Log message:
        Fully parse AS3 blocks of code.  (Doesn't yet verify the code or 
populate
        symbol tables.)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4369&r2=1.4370
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/tu_file.h?cvsroot=gnash&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/gnash/server/impl.cpp?cvsroot=gnash&r1=1.120&r2=1.121
http://cvs.savannah.gnu.org/viewcvs/gnash/server/stream.cpp?cvsroot=gnash&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/gnash/server/stream.h?cvsroot=gnash&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/Makefile.am?cvsroot=gnash&r1=1.37&r2=1.38
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/abc_block.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/abc_block.h?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.cpp?cvsroot=gnash&r1=1.139&r2=1.140
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.h?cvsroot=gnash&r1=1.21&r2=1.22

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4369
retrieving revision 1.4370
diff -u -b -r1.4369 -r1.4370
--- ChangeLog   21 Sep 2007 12:12:32 -0000      1.4369
+++ ChangeLog   21 Sep 2007 13:40:31 -0000      1.4370
@@ -1,3 +1,12 @@
+2007-09-21 Chad Musick <address@hidden>
+
+       * libbase/tu_file.h: Add support for reading 64-bit doubles.
+       * server/impl.cpp: Add abc_loader to list of loaders.
+       * server/stream.cpp,.h: Support necessary read types for AS3.
+       * server/parser/Makefile.am: Add new files
+       * server/parser/abc_block.cpp,.h: Changes to parse AS3.
+       * server/swf/tag_loaders.cpp,.h: Loader for action block (AS3)
+
 2007-09-21 Sandro Santilli <address@hidden>
 
        * server/dlist.h (testInvariant): fix a cast discarding const

Index: libbase/tu_file.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/tu_file.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- libbase/tu_file.h   14 May 2007 21:39:48 -0000      1.16
+++ libbase/tu_file.h   21 Sep 2007 13:40:31 -0000      1.17
@@ -119,6 +119,19 @@
        return(result);
     }
        
+       /// \brief Read a 64-bit word from a little-ending stream,
+       /// returning it as a native-endian word.
+       //
+       /// TODO: define what happens when the stream is in
+       ///       error condition, see get_error().
+       /// TODO: define a platform-neutral type for 64 bits.
+       long double read_le_double64() {
+               return static_cast<long double> (
+                       static_cast<int64_t> (read_le32()) |
+                       static_cast<int64_t> (read_le32()) << 32
+               );
+       }
+
     /// \brief Read a 16-bit word from a little-endian stream.
     //
     /// TODO: define what happens when the stream

Index: server/impl.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/impl.cpp,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -b -r1.120 -r1.121
--- server/impl.cpp     19 Sep 2007 14:20:49 -0000      1.120
+++ server/impl.cpp     21 Sep 2007 13:40:31 -0000      1.121
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: impl.cpp,v 1.120 2007/09/19 14:20:49 cmusick Exp $ */
+/* $Id: impl.cpp,v 1.121 2007/09/21 13:40:31 cmusick Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -251,7 +251,7 @@
        register_tag_loader(SWF::PLACEOBJECT3, PlaceObject2Tag::loader); // 70
        register_tag_loader(SWF::IMPORTASSETS2, import_loader); // 71
 
-        register_tag_loader(SWF::DOABC, fixme_loader); // 72 -- AS3 codeblock.
+        register_tag_loader(SWF::DOABC, abc_loader); // 72 -- AS3 codeblock.
        register_tag_loader(SWF::DEFINEALIGNZONES, 
DefineFontAlignZonesTag::loader); // 73
 
        register_tag_loader(SWF::CSMTEXTSETTINGS, fixme_loader); // 74
@@ -259,7 +259,7 @@
         register_tag_loader(SWF::SYMBOLCLASS, fixme_loader); // 76 
        register_tag_loader(SWF::METADATA, metadata_loader); // 77
        register_tag_loader(SWF::DEFINESCALINGGRID, fixme_loader); // 78
-        register_tag_loader(SWF::DOABCDEFINE, fixme_loader); // 79 -- AS3 
codeblock.
+        register_tag_loader(SWF::DOABCDEFINE, abc_loader); // 82 -- AS3 
codeblock.
        register_tag_loader(SWF::DEFINESHAPE4, define_shape_loader); // 83
        register_tag_loader(SWF::DEFINEMORPHSHAPE2, define_shape_morph_loader); 
// 84
 

Index: server/stream.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/stream.cpp,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- server/stream.cpp   27 Aug 2007 18:52:58 -0000      1.31
+++ server/stream.cpp   21 Sep 2007 13:40:31 -0000      1.32
@@ -254,6 +254,13 @@
                return static_cast<float> (m_input->read_le32());
        }
 
+       // Read a 64-bit double value
+       long double stream::read_d64()
+       {
+               align();
+               return m_input->read_le_double64();
+       }
+
        uint8_t stream::read_u8() { align(); return m_input->read_byte(); }
        int8_t  stream::read_s8() { align(); return m_input->read_byte(); }
        uint16_t        stream::read_u16()

Index: server/stream.h
===================================================================
RCS file: /sources/gnash/gnash/server/stream.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- server/stream.h     28 Aug 2007 13:12:38 -0000      1.29
+++ server/stream.h     21 Sep 2007 13:40:32 -0000      1.30
@@ -72,6 +72,10 @@
                float   read_float();
 
                /// \brief
+               /// Read 64-bit double values.
+               long double read_d64();
+
+               /// \brief
                /// Discard any left-over bits from previous bit reads
                void    align()
                {
@@ -109,6 +113,44 @@
                int32_t  read_s32();
 
                /// \brief
+               /// Read a variable length unsigned 32-bit value from the 
stream.
+               /// These values continue until either the high bit is not set 
or
+               /// until 5 bytes have been read.
+               uint32_t read_V32()
+               {
+                       uint32_t res = read_u8();
+                       if (!(res & 0x00000080))
+                               return res;
+                       res = (res & 0x0000007F) | read_u8() << 7;
+                       if (!(res & 0x00004000))
+                               return res;
+                       res = (res & 0x00003FFF) | read_u8() << 14;
+                       if (!(res & 0x00200000))
+                               return res;
+                       res = (res & 0x001FFFFF) | read_u8() << 21;
+                       if (!(res & 0x10000000))
+                               return res;
+                       res = (res & 0x0FFFFFFF) | read_u8() << 28;
+                       return res;
+               }
+
+               /// \brief
+               /// Skip a variable length unsigned 32-bit value in the stream.
+               /// This is faster than doing the bitwise arithmetic of full 
reading.
+               void skip_V32()
+               {
+                       if (!(read_u8() & 0x80))
+                               return;
+                       if (!(read_u8() & 0x80))
+                               return;
+                       if (!(read_u8() & 0x80))
+                               return;
+                       if (!(read_u8() & 0x80))
+                               return;
+                       static_cast<void> (read_u8());
+               }
+
+               /// \brief
                /// Read a length in a byte or three.
                //
                /// If the byte == 0xff, read the lenght in 

Index: server/parser/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/parser/Makefile.am,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -b -r1.37 -r1.38
--- server/parser/Makefile.am   1 Jul 2007 10:54:33 -0000       1.37
+++ server/parser/Makefile.am   21 Sep 2007 13:40:32 -0000      1.38
@@ -15,7 +15,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-# $Id: Makefile.am,v 1.37 2007/07/01 10:54:33 bjacques Exp $
+# $Id: Makefile.am,v 1.38 2007/09/21 13:40:32 cmusick Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -45,6 +45,7 @@
        $(NULL)
 
 libgnashparser_la_SOURCES = \
+       abc_block.cpp \
        action_buffer.cpp \
        bitmap_character_def.cpp \
        BitmapMovieDefinition.cpp \
@@ -61,6 +62,7 @@
 
 noinst_HEADERS = \
        Timeline.h      \
+       abc_block.h \
        action_buffer.h \
        button_character_def.h \
        character_def.h \
@@ -71,6 +73,7 @@
        morph2_character_def.h \
        movie_definition.h \
        movie_def_impl.h \
+       Namespace.h \
        shape_character_def.h \
        sound_definition.h \
        sprite_definition.h \

Index: server/parser/abc_block.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/abc_block.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- server/parser/abc_block.cpp 20 Sep 2007 17:07:21 -0000      1.1
+++ server/parser/abc_block.cpp 21 Sep 2007 13:40:32 -0000      1.2
@@ -20,6 +20,10 @@
 
 #include "abc_block.h"
 #include "stream.h"
+#include "VM.h"
+#include "log.h"
+
+#define ERR(x) IF_VERBOSE_MALFORMED_SWF(log_swferror x;);
 
 namespace gnash {
 
@@ -41,7 +45,10 @@
                mSlotId = in->read_V32();
                mTypeIndex = in->read_V32();
                mValueIndex = in->read_V32();
+               if (mValueIndex)
                mValueIndexTypeIndex = in->read_u8();
+               else
+                       mValueIndexTypeIndex = 0;
                break;
        }
        case KIND_METHOD:
@@ -68,6 +75,7 @@
        }
        default:
        {
+               ERR((_("Action Block: Unknown trait kind (%d).\n"), mKind));
                return false;
        }
        } // end of switch
@@ -95,24 +103,27 @@
 
        std::vector<abc_Trait> traitVec;
 
-       // Minor version.
-       static_cast<void>(in->read_u16());
-       // Major version.
-       static_cast<void>(in->read_u16());
+       // Minor version, major version.
+       uint32_t version = (in->read_u16()) | (in->read_u16() << 16);
+       ERR((_("Abc Version: %d.%d\n"), (version & 0xFFFF0000) >> 16, (version 
& 0x0000FFFF)));
 
        // A block of signed integers. Count overshoots by 1,
        // and the 0 is used to signal a no-op.
        uint32_t intPoolCount = in->read_V32();
        mIntegerPool.resize(intPoolCount);
+       if (intPoolCount)
+               mIntegerPool[0] = 0;
        for (unsigned int i = 1; i < intPoolCount; ++i)
        {
-               mIntegerPool[i] = in->read_s32();
+               mIntegerPool[i] = static_cast<int32_t> (in->read_V32());
        }
        
        // A block of unsigned integers. Count overshoots by 1,
        // and the 0 is used to signal a no-op.
        uint32_t uIntPoolCount = in->read_V32();
        mUIntegerPool.resize(uIntPoolCount);
+       if (uIntPoolCount)
+               mUIntegerPool[0] = 0;
        for (unsigned int i = 1; i < uIntPoolCount; ++i)
        {
                mUIntegerPool[i] = in->read_V32();
@@ -122,6 +133,8 @@
        // and the 0 is used to signal a no-op.
        uint32_t doublePoolCount = in->read_V32();
        mDoublePool.resize(doublePoolCount);
+       if (doublePoolCount)
+               mDoublePool[0] = 0.0;
        for (unsigned int i = 1; i < doublePoolCount; ++i)
        {
                mDoublePool[i] = in->read_d64();
@@ -131,24 +144,28 @@
        // entry used to signal a no-op.
        uint32_t stringPoolCount = in->read_V32();
        mStringPool.resize(stringPoolCount);
+       mStringPoolTableIds.resize(stringPoolCount);
+       if (stringPoolCount)
+       {
+               mStringPool[0] = "";
+               mStringPoolTableIds[0] = 0;
+       }
        for (unsigned int i = 1; i < stringPoolCount; ++i)
        {
                uint32_t length = in->read_V32();
                in->read_string_with_length(length, mStringPool[i]);
-       }
-
-       // Many of the strings will correspond to string table entries --
-       // fill this up as we find these.
-       mStringPoolTableIds.resize(stringPoolCount);
-       for (unsigned int i = 0; i < stringPoolCount; ++i)
                mStringPoolTableIds[i] = 0;
+       }
 
        // These are namespaces, individually. The counter overshoots by
        // 1, with the 0th entry used to signal a wildcard.
        uint32_t namespacePoolCount = in->read_V32();
        mNamespacePool.resize(namespacePoolCount);
+       if (namespacePoolCount)
+       {
        mNamespacePool[0].mUri = mNamespacePool[0].mPrefix = 0;
        mNamespacePool[0].mKind = Namespace::KIND_NORMAL;
+       }
        for (unsigned int i = 1; i < namespacePoolCount; ++i)
        {
                uint8_t kind = in->read_u8();
@@ -169,8 +186,12 @@
                        // And reset the nameIndex for the uri.
                        nameIndex = mStringPoolTableIds[nameIndex];
                }
-               else
-                       nameIndex = 0;
+               else if (nameIndex >= mStringPool.size())
+               {
+                       ERR((_("Action Block: Out of Bound string for 
namespace.\n")));
+                       return false;
+               }
+
                // And set the name in the Namespace itself.
                mNamespacePool[i].mUri = nameIndex;
                // The prefix is unknown right now.
@@ -180,8 +201,11 @@
        // These are sets of namespaces, which use the individual ones above.
        uint32_t namespaceSetPoolCount = in->read_V32();
        mNamespaceSetPool.resize(namespaceSetPoolCount);
+       if (namespaceSetPoolCount)
+       {
        // The base namespace set is empty.
        mNamespaceSetPool[0].resize(0);
+       }
        for (unsigned int i = 1; i < namespaceSetPoolCount; ++i)
        {
                // These counts are not inflated the way the others are.
@@ -193,6 +217,7 @@
                        if (!selection || selection >= namespacePoolCount)
                        {
                                // Reached a bad selection.
+                               ERR((_("Action Block: Out of Bound namespace in 
namespace set.\n")));
                                return false;
                        }
                        mNamespaceSetPool[i][j] = &mNamespacePool[selection];
@@ -202,8 +227,9 @@
        // A list of the multinames. The counter overestimates by 1, and the
        // 0th is used as a no-op.
        uint32_t multinamePoolCount = in->read_V32();
+
        mMultinamePool.resize(multinamePoolCount);
-       for (unsigned int i = 0; i < multinamePoolCount; ++i)
+       for (unsigned int i = 1; i < multinamePoolCount; ++i)
        {
                uint8_t kind = in->read_u8();
                mMultinamePool[i].mKind = 
static_cast<abc_Multiname::kinds>(kind);
@@ -239,7 +265,10 @@
                        nsset = in->read_V32();
                        // 0 is not a valid nsset.
                        if (!nsset)
+                       {
+                               ERR((_("Action Block: 0 selection for namespace 
set is invalid.\n")));
                                return false;
+                       }
                        break;
                }
                case abc_Multiname::KIND_MultinameL:
@@ -248,22 +277,35 @@
                        nsset = in->read_V32();
                        // 0 is not a valid nsset.
                        if (!nsset)
+                       {
+                               ERR((_("Action Block: 0 selection for namespace 
set is invalid.\n")));
                                return false;
+                       }
                        break;
                }
                default:
                {
                        // Unknown type.
+                       ERR((_("Action Block: Unknown multiname type (%d).\n"), 
kind));
                        return false;
                } // End of cases.
                } // End of switch.
 
                if (name >= mStringPool.size())
+               {
+                       ERR((_("Action Block: Out of Bound string for 
Multiname.\n")));
                        return false; // Bad name.
+               }
                if (ns >= mNamespacePool.size())
+               {
+                       ERR((_("Action Block: Out of Bound namespace for 
Multiname.\n")));
                        return false; // Bad namespace.
+               }
                if (nsset >= mNamespaceSetPool.size())
+               {
+                       ERR((_("Action Block: Out of Bound namespace set for 
Multiname.\n")));
                        return false; // Bad namespace set.
+               }
 
                // The name should be in the string table.
                if (name && mStringPoolTableIds[name] == 0)
@@ -289,7 +331,11 @@
                uint32_t return_type = in->read_V32();
 
                if (return_type >= mMultinamePool.size())
+               {
+                       ERR((_("Action Block: Out of Bound return type for "
+                               "method info (%d).\n"), return_type));
                        return false;
+               }
 
                method.mReturnType = &mMultinamePool[return_type];
 
@@ -299,7 +345,11 @@
                        // The parameter type.
                        uint32_t ptype = in->read_V32();
                        if (ptype >= mMultinamePool.size())
+                       {
+                               ERR((_("Action Block: Out of Bound parameter 
type "
+                                       "for method info (%d).\n"), ptype));
                                return false;
+                       }
                        method.mParameters[j] = &mMultinamePool[ptype];
                }
                // We ignore the name_index
@@ -334,15 +384,19 @@
        } // End of method loop.
 
        // Following is MetaData, which we will ignore.
-       in->skip_V32(); // A name index.
        uint32_t metaCount = in->read_V32();
        for (unsigned int i = 0; i < metaCount; ++i)
        {
+               in->skip_V32(); // A name index.
+               uint32_t metaInternalCount = in->read_V32();
+               for (unsigned int j = 0; j < metaInternalCount; ++j)
+               {
                // key and values are _not_ in this order (they group 
together), but
                // we are just skipping anyway.
                in->skip_V32();
                in->skip_V32();
        }
+       }
 
        // Classes count.
        uint32_t classCount = in->read_V32();
@@ -354,15 +408,22 @@
        {
                abc_Instance& instance = mInstances[i];
                uint32_t index = in->read_V32();
-               if (!index || index >= mMultinamePool.size())
+               // 0 is allowed as a name, typically for the last entry.
+               if (index >= mMultinamePool.size())
+               {
+                       ERR((_("Action Block: Out of Bound instance name 
(%d).\n"), index));
                        return false; // Name out of bounds.
+               }
                instance.mName = &mMultinamePool[index];
 
                uint32_t super_index = in->read_V32();
                if (!super_index)
                        instance.mSuperType = NULL;
                else if (super_index >= mMultinamePool.size())
+               {
+                       ERR((_("Action Block: Out of Bound super type 
(%d).\n"), index));
                        return false; // Bad index.
+               }
                else
                        instance.mSuperType = &mMultinamePool[super_index];
 
@@ -374,7 +435,11 @@
                {
                        uint32_t ns_index = in->read_V32();
                        if (ns_index >= mNamespacePool.size())
+                       {
+                               ERR((_("Action Block: Out of Bound namespace 
for "
+                                       "instance protected namespace 
(%d).\n"), ns_index));
                                return false;
+                       }
                        if (ns_index)
                                instance.mProtectedNamespace = 
&mNamespacePool[ns_index];
                }
@@ -385,15 +450,24 @@
                for (unsigned int j = 0; j < interfaceCount; ++j)
                {
                        uint32_t i_index = in->read_V32();
-                       if (!i_index || i_index >= mMultinamePool.size())
+                       // 0 is allowed as an interface, typically for the last 
one.
+                       if (i_index >= mMultinamePool.size())
+                       {
+                               ERR((_("Action Block: Out of Bound name for 
interface. "
+                                       "(%d)\n"), i_index));
                                return false; // Bad read.
+                       }
                        instance.mInterfaces[j] = &mMultinamePool[i_index];
                }
 
                // Reach into the methods list.
                uint32_t methodsOffset = in->read_V32();
                if (methodsOffset >= mMethods.size())
+               {
+                       ERR((_("Action Block: Out of Bound method for 
interface. (%d)\n"),
+                               methodsOffset));
                        return false; // Bad method.
+               }
                instance.mMethod = &mMethods[methodsOffset];
 
                // Now parse the traits.
@@ -402,19 +476,30 @@
                instance.mTraits.resize(traitsCount);
                for (unsigned int j = 0; j < traitsCount; ++j)
                {
-                       instance.mTraits[j].read(in);
+                       if (!instance.mTraits[j].read(in))
+                               return false;
                }
        } // end of instances list
 
        // Now the classes are read. TODO: Discover what these do.
        for (unsigned int i = 0; i < classCount; ++i)
        {
-               uint32_t initial_method_offset = in->read_V32();
+               abc_Class& cClass = mClasses[i];
+               uint32_t method_offset = in->read_V32();
+               if (method_offset >= mMethods.size())
+               {
+                       ERR((_("Action Block: Out of Bound method for class 
(%d).\n"),
+                               method_offset));
+                       return false;
+               }
+               cClass.mMethod = &mMethods[method_offset];
+
                uint32_t traitsCount = in->read_V32();
-               traitVec.resize(traitsCount);
+               cClass.mTraits.resize(traitsCount);
                for (unsigned int j = 0; j < traitsCount; ++j)
                {
-                       traitVec[j].read(in);
+                       if (!cClass.mTraits[j].read(in))
+                               return false;
                }
        } // end of classes list
 
@@ -423,20 +508,41 @@
        mScripts.resize(scriptCount);
        for (unsigned int i = 0; i < scriptCount; ++i)
        {
-               uint32_t initial_method_offset = in->read_V32();
+               abc_Script& script = mScripts[i];
+               uint32_t method_offset = in->read_V32();
+               if (method_offset >= mMethods.size())
+               {
+                       ERR((_("Action Block: Out of Bound method for script 
(%d).\n"),
+                               method_offset));
+                       return false;
+               }
+               script.mMethod = &mMethods[method_offset];
+
                uint32_t traitsCount = in->read_V32();
-               traitVec.resize(traitsCount);
+               script.mTraits.resize(traitsCount);
                for (unsigned int j = 0; j < traitsCount; ++j)
                {
-                       traitVec[j].read(in);
+                       if (!script.mTraits[j].read(in))
+                               return false;
                }
        }
 
        // The method bodies. TODO: Use these.
        uint32_t methodBodyCount = in->read_V32();
+       mBodies.resize(methodBodyCount);
        for (unsigned int i = 0; i < methodBodyCount; ++i)
        {
+               abc_MethodBody& method = mBodies[i];
+
                uint32_t method_info = in->read_V32();
+               if (method_info >= mMethods.size())
+               {
+                       ERR((_("Action Block: Out of Bound method for method 
body. "
+                               "(%d)\n"), method_info));
+                       return false; // Too big.
+               }
+               method.mMethod = &mMethods[method_info];
+
                // We don't care about the maximum stack size. Discard it.
                in->skip_V32();
                // We don't care about the maximum register size. Discard it.
@@ -448,31 +554,72 @@
                // How long is the code?
                uint32_t code_length = in->read_V32();
                // And the code:
+               method.mCode.resize(code_length);
+               unsigned int got_length;
+               if ((got_length = in->read(method.mCode.data(), code_length)) 
!= code_length)
+               {
+                       ERR((_("Action Block: Not enough body. Wanted %d but 
got %d.\n"),
+                               code_length, got_length));
+                       return false; // Not enough bytes.
+               }
+
                // TODO: Grab code_length bytes for the code.
                uint32_t exceptions_count = in->read_V32();
+               method.mExceptions.resize(exceptions_count);
                for (unsigned int j = 0; j < exceptions_count; ++j)
                {
-                       // Where the try block ? begins and ends.
-                       uint32_t start_offset = in->read_V32();
-                       uint32_t end_offset = in->read_V32();
-                       // Where the catch block is located.
-                       uint32_t catch_offset = in->read_V32();
+                       abc_Exception& exceptor = method.mExceptions[j];
+
+                       // Where the try block begins and ends.
+                       exceptor.mStart = in->read_V32();
+                       exceptor.mEnd = in->read_V32();
+                       
+                       // Where to go if this exception is activated.
+                       exceptor.mCatch = in->read_V32();
+                       
                        // What types should be caught.
                        uint32_t catch_type = in->read_V32();
+                       if (catch_type >= mMultinamePool.size())
+                       {
+                               ERR((_("Action Block: Out of Bound type for 
exception "
+                                       "(%d).\n"), catch_type));
+                               return false; // Bad type.
+                       }
+                       exceptor.mType = catch_type ? 
&mMultinamePool[catch_type] : NULL;
+
                        // If caught, what is the variable name.
-                       uint32_t catch_var_name = in->read_V32();
+                       if (version != (46 << 16) | 15) // In version 46.15, no 
names.
+                       {
+                               uint32_t cvn = in->read_V32();
+                               if (cvn >= mMultinamePool.size())
+                               {
+                                       ERR((_("Action Block: Out of Bound name 
for caught "
+                                               "exception. (%d)\n"), cvn));
+                                       return false; // Bad name
+                               }
+                               exceptor.mName = cvn ? &mMultinamePool[cvn] : 
NULL;
                }
+                       else
+                               exceptor.mName = NULL;
+               } // End of exceptions
+
                uint32_t traitsCount = in->read_V32();
-               traitVec.resize(traitsCount);
+               method.mTraits.resize(traitsCount);
                for (unsigned int j = 0; j < traitsCount; ++j)
                {
-                       traitVec[j].read(in);
-               }
+                       if (!method.mTraits[j].read(in))
+                               return false;
        }
+       } // End of method bodies
 
        // If flow reaches here, everything went fine.
        return true;
 }
 
+abc_block::abc_block() : mStringTable(&VM::get().getStringTable())
+{
+       /**/
+}
+
 }; /* namespace gnash */
 

Index: server/parser/abc_block.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/abc_block.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- server/parser/abc_block.h   20 Sep 2007 17:07:21 -0000      1.1
+++ server/parser/abc_block.h   21 Sep 2007 13:40:32 -0000      1.2
@@ -23,11 +23,11 @@
 
 #include <vector>
 #include <string>
+#include <boost/scoped_array.hpp>
 
 #include "gnash.h"
 #include "stream.h"
 #include "string_table.h"
-
 #include "Namespace.h"
 
 namespace gnash {
@@ -89,7 +89,6 @@
        std::vector<abc_Multiname*> mParameters; // The types, not the names.
        uint8_t mFlags;
        std::vector<optional_parameter> mOptionalParameters;
-
 };
 
 class abc_Instance
@@ -141,6 +140,39 @@
        bool read(stream* in);
 };
 
+class abc_Class
+{
+public:
+       abc_Method *mMethod;
+       std::vector<abc_Trait> mTraits;
+};
+
+class abc_Script
+{
+public:
+       abc_Method *mMethod;
+       std::vector<abc_Trait> mTraits;
+};
+
+class abc_Exception
+{
+public:
+       uint32_t mStart;
+       uint32_t mEnd;
+       uint32_t mCatch;
+       abc_Multiname* mType;
+       abc_Multiname* mName;
+};
+
+class abc_MethodBody
+{
+public:
+       abc_Method *mMethod;
+       std::vector<abc_Exception> mExceptions;
+       std::vector<abc_Trait> mTraits;
+       std::vector<char> mCode;
+};
+
 }; // namespace abc_parsing
 
 typedef std::vector<Namespace*> NamespaceSet;
@@ -158,17 +190,16 @@
        std::vector<abc_parsing::abc_Method> mMethods;
        std::vector<abc_parsing::abc_Multiname> mMultinamePool;
        std::vector<abc_parsing::abc_Instance> mInstances;
-       std::vector<uint32_t> mClasses; // TODO: Fix this.
-       std::vector<uint32_t> mScripts; // TODO: Fix this.
-       std::vector<uint32_t> mBodies; // TODO: Fix this.
+       std::vector<abc_parsing::abc_Class> mClasses; 
+       std::vector<abc_parsing::abc_Script> mScripts;
+       std::vector<abc_parsing::abc_MethodBody> mBodies;
 
        string_table* mStringTable;
 
 public:
-       int32_t poolInteger(uint32_t index) const;
-       uint32_t poolUInteger(uint32_t index) const;
-       
        bool read(stream* in);
+
+       abc_block();
 };
 
 }; /* namespace gnash */

Index: server/swf/tag_loaders.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/tag_loaders.cpp,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -b -r1.139 -r1.140
--- server/swf/tag_loaders.cpp  17 Sep 2007 14:38:34 -0000      1.139
+++ server/swf/tag_loaders.cpp  21 Sep 2007 13:40:32 -0000      1.140
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: tag_loaders.cpp,v 1.139 2007/09/17 14:38:34 strk Exp $ */
+/* $Id: tag_loaders.cpp,v 1.140 2007/09/21 13:40:32 cmusick Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -54,6 +54,7 @@
 #include "GnashException.h"
 #include "video_stream_def.h"
 #include "sound_definition.h"
+#include "abc_block.h"
 
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
@@ -1953,6 +1954,30 @@
 
 }
 
+void
+abc_loader(stream* in, tag_type tag, movie_definition* /*m*/)
+{
+       assert(tag == SWF::DOABC
+               || tag == SWF::DOABCDEFINE); // 72 or 82
+
+       abc_block a;
+
+       if (tag == SWF::DOABCDEFINE)
+       {
+               // Skip the 'flags' until they are actually used.
+               static_cast<void> (in->read_u32());
+               std::string name = in->read_string();
+               name.c_str();
+       }
+
+       bool success = a.read(in);
+       if (success)
+       {
+               /* TODO: Run the script if needed. */
+       }
+
+       log_unimpl(_("Action Block tags are parsed but not yet used"));
+}
 
 } // namespace gnash::SWF::tag_loaders
 } // namespace gnash::SWF

Index: server/swf/tag_loaders.h
===================================================================
RCS file: /sources/gnash/gnash/server/swf/tag_loaders.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/swf/tag_loaders.h    22 Aug 2007 13:09:10 -0000      1.21
+++ server/swf/tag_loaders.h    21 Sep 2007 13:40:32 -0000      1.22
@@ -19,7 +19,7 @@
 //
 //
 
-/* $Id: tag_loaders.h,v 1.21 2007/08/22 13:09:10 cmusick Exp $ */
+/* $Id: tag_loaders.h,v 1.22 2007/09/21 13:40:32 cmusick Exp $ */
 
 #ifndef GNASH_SWF_TAG_LOADERS_H
 #define GNASH_SWF_TAG_LOADERS_H
@@ -142,6 +142,8 @@
 /// Load a SWF::SOUNDSTREAMBLOCK tag.
 void   sound_stream_block_loader(stream*, tag_type, movie_definition*);
 
+void   abc_loader(stream*, tag_type, movie_definition*);
+
 void
 define_video_loader(stream* in, tag_type tag, movie_definition* m);
 




reply via email to

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