gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog libbase/GnashException.h server...


From: Benjamin Wolsey
Subject: [Gnash-commit] gnash ChangeLog libbase/GnashException.h server...
Date: Wed, 07 May 2008 09:41:14 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Benjamin Wolsey <bwy>   08/05/07 09:41:14

Modified files:
        .              : ChangeLog 
        libbase        : GnashException.h 
        server         : as_object.cpp as_object.h sprite_instance.cpp 
        server/parser  : action_buffer.cpp action_buffer.h 
        server/vm      : ASHandlers.cpp action.cpp 

Log message:
                * libbase/GnashException.h: make ActionException ctor protected
                  so that it can't be used directly. Add ActionParserException
                  subclass for bad action_buffer accesses. Make ActionTypeError
                  a subclass of ActionException. GnashException should perhaps
                  get the same treatment, but is used directly in a number
                  of places.
                * server/sprite_instance.cpp: catch ActionTypeError.
                * server/as_object.h (ensureType): throw ActionTypeError.
                * server/as_object.cpp: catch ActionTypeError.
                * server/action.cpp: throw/catch ActionTypeError.
                * server/parser/action_buffer.h: the actual point of these
                  changes: check for out-of-buffer access and throw an 
                  ActionParserException. Drop unused method get_length(). Add
                  assertions to other methods. Use direct vector access instead
                  of .at() now that boundaries are checked. Fixes bug #23185
                * server/parser/action_buffer.cpp: Add a NULL terminator to 
buffer
                  if no END tag found, to prevent string reads going past the 
end of
                  the buffer.
                * server/vm/AShandlers.cpp (SWFHandlers::execute()): catch
                  ActionParserException and stop parsing on error.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6537&r2=1.6538
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/GnashException.h?cvsroot=gnash&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.cpp?cvsroot=gnash&r1=1.120&r2=1.121
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.h?cvsroot=gnash&r1=1.109&r2=1.110
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.531&r2=1.532
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/action_buffer.cpp?cvsroot=gnash&r1=1.39&r2=1.40
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/action_buffer.h?cvsroot=gnash&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.235&r2=1.236
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/action.cpp?cvsroot=gnash&r1=1.36&r2=1.37

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6537
retrieving revision 1.6538
diff -u -b -r1.6537 -r1.6538
--- ChangeLog   7 May 2008 09:15:16 -0000       1.6537
+++ ChangeLog   7 May 2008 09:41:12 -0000       1.6538
@@ -1,3 +1,26 @@
+2008-05-07 Benjamin Wolsey <address@hidden>
+
+       * libbase/GnashException.h: make ActionException ctor protected
+         so that it can't be used directly. Add ActionParserException
+         subclass for bad action_buffer accesses. Make ActionTypeError
+         a subclass of ActionException. GnashException should perhaps
+         get the same treatment, but is used directly in a number
+         of places.
+       * server/sprite_instance.cpp: catch ActionTypeError.
+       * server/as_object.h (ensureType): throw ActionTypeError.
+       * server/as_object.cpp: catch ActionTypeError.
+       * server/action.cpp: throw/catch ActionTypeError.
+       * server/parser/action_buffer.h: the actual point of these
+         changes: check for out-of-buffer access and throw an 
+         ActionParserException. Drop unused method get_length(). Add
+         assertions to other methods. Use direct vector access instead
+         of .at() now that boundaries are checked. Fixes bug #23185
+       * server/parser/action_buffer.cpp: Add a NULL terminator to buffer
+         if no END tag found, to prevent string reads going past the end of
+         the buffer.
+       * server/vm/AShandlers.cpp (SWFHandlers::execute()): catch
+         ActionParserException and stop parsing on error.
+
 2008-05-07 Sandro Santilli <address@hidden>
 
        * server/swf/tag_loaders.cpp (sound_stream_head_loader): log no

Index: libbase/GnashException.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/GnashException.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- libbase/GnashException.h    21 Jan 2008 20:55:43 -0000      1.12
+++ libbase/GnashException.h    7 May 2008 09:41:13 -0000       1.13
@@ -73,7 +73,7 @@
 class ActionException: public GnashException
 {
 
-public:
+protected:
 
        ActionException(const std::string& s)
                :
@@ -85,6 +85,8 @@
                GnashException("ActionScript error")
        {}
 
+public:
+
        virtual ~ActionException() throw() {}
 
 };
@@ -94,19 +96,19 @@
 /// When this exception is thrown, current execution should
 /// be aborted, stacks and registers cleaning included.
 ///
-class ActionLimitException: public GnashException
+class ActionLimitException: public ActionException
 {
 
 public:
 
        ActionLimitException(const std::string& s)
                :
-               GnashException(s)
+               ActionException(s)
        {}
 
        ActionLimitException()
                :
-               GnashException("ActionScript limit hit")
+               ActionException("ActionScript limit hit")
        {}
 
        virtual ~ActionLimitException() throw() {}
@@ -138,6 +140,28 @@
 
 };
 
+/// An action parsing error, thrown on illegal
+/// action buffer access.
+class ActionParserException: public ActionException
+{
+
+public:
+
+       ActionParserException(const std::string& s)
+               :
+               ActionException(s)
+       {}
+
+       ActionParserException()
+               :
+               ActionException("Action parser exception")
+       {}
+
+       virtual ~ActionParserException() throw() {}
+
+};
+
+
 } // namespace gnash
 
 #endif // def _GNASH_GNASHEXCEPTION__H

Index: server/as_object.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.cpp,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -b -r1.120 -r1.121
--- server/as_object.cpp        5 May 2008 14:39:05 -0000       1.120
+++ server/as_object.cpp        7 May 2008 09:41:13 -0000       1.121
@@ -228,7 +228,7 @@
                // will be logged by outer catcher
                throw;
        }
-       catch (ActionException& exc)
+       catch (ActionTypeError& exc)
        {
                // TODO: check if this should be an 'as' error.. (log_aserror)
                log_error(_("Caught exception: %s"), exc.what());
@@ -595,7 +595,7 @@
 
                        prop->clearVisible(_vm.getSWFVersion());
                }
-               catch (ActionException& exc)
+               catch (ActionTypeError& exc)
                {
                        log_aserror(_("%s: Exception %s. Will create a new 
member"),
                                _vm.getStringTable().value(key).c_str(), 
exc.what());
@@ -697,7 +697,7 @@
                        prop->setValue(*this, newVal);
                        return std::make_pair(true, true);
                }
-               catch (ActionException& exc)
+               catch (ActionTypeError& exc)
                {
                        log_debug(_("%s: Exception %s. Will create a new 
member"),
                                _vm.getStringTable().value(key).c_str(), 
exc.what());

Index: server/as_object.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.h,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -b -r1.109 -r1.110
--- server/as_object.h  5 May 2008 14:39:05 -0000       1.109
+++ server/as_object.h  7 May 2008 09:41:13 -0000       1.110
@@ -1175,7 +1175,7 @@
                std::string msg = "builtin method or gettersetter for " +
                        target + " called from " + source + " instance.";
 
-               throw ActionException(msg);
+               throw ActionTypeError(msg);
        }
        return ret;
 }

Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.531
retrieving revision 1.532
diff -u -b -r1.531 -r1.532
--- server/sprite_instance.cpp  6 May 2008 12:14:36 -0000       1.531
+++ server/sprite_instance.cpp  7 May 2008 09:41:13 -0000       1.532
@@ -2502,7 +2502,7 @@
   {
     try { *val = prop->getValue(*this); }
     catch (ActionLimitException&) { throw; }
-    catch (ActionException& ex) { log_error(_("Caught exception: %s"), 
ex.what()); return false; }
+    catch (ActionTypeError& ex) { log_error(_("Caught exception: %s"), 
ex.what()); return false; }
     return true;
   }
 
@@ -2549,7 +2549,11 @@
     assert(owner != this);
     try { *val = prop->getValue(*this); }
     catch (ActionLimitException&) { throw; }
-    catch (ActionException& ex) { log_error(_("Caught exception: %s"), 
ex.what()); return false; }
+    catch (ActionTypeError& ex)
+    {
+        log_error(_("Caught exception: %s"), ex.what());
+        return false;
+    }
     return true;
   }
 

Index: server/parser/action_buffer.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/action_buffer.cpp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -b -r1.39 -r1.40
--- server/parser/action_buffer.cpp     6 May 2008 16:15:57 -0000       1.39
+++ server/parser/action_buffer.cpp     7 May 2008 09:41:14 -0000       1.40
@@ -96,13 +96,19 @@
        // NOTE: it is common to find such movies, swfmill is known to write
        //       DoAction w/out the terminating END tag
        //
-       IF_VERBOSE_MALFORMED_SWF(
        if ( m_buffer.back() != SWF::ACTION_END )
        {
+        // Add a null terminator so read_string won't read off
+        // the end of the buffer.
+        m_buffer.resize(size + 1);
+        m_buffer[size] = 0;
+
+           IF_VERBOSE_MALFORMED_SWF(
                log_swferror(_("Action buffer starting at offset %lu doesn't 
end with an END tag"),
                        startPos);
-       }
        );
+    }
+    
 }
 
 /*public*/

Index: server/parser/action_buffer.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/action_buffer.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- server/parser/action_buffer.h       27 Mar 2008 13:41:26 -0000      1.27
+++ server/parser/action_buffer.h       7 May 2008 09:41:14 -0000       1.28
@@ -26,11 +26,12 @@
 #include "gnash.h"
 #include "types.h"
 
-//#include <cwchar>
 #include <boost/cstdint.hpp> // for boost::uint8_t
 #include <vector> // for composition
 
+#include "GnashException.h"
 #include "smart_ptr.h"
+#include "log.h" // For gettext macro
 
 // Forward declarations
 namespace gnash {
@@ -70,18 +71,16 @@
 
        bool is_null() const
        {
-               return (m_buffer.size() < 1 || m_buffer.at(0) == 0);
+               return (m_buffer.size() < 1 || m_buffer[0] == 0);
        }
 
-       // kept for backward compatibility, should drop and see
-       // what breaks.
-       size_t get_length() const { return size(); }
-
        size_t size() const { return m_buffer.size(); }
 
        boost::uint8_t operator[] (size_t off) const
        {
-               assert(off < m_buffer.size() );
+               if (off >= m_buffer.size()) {
+                   throw ActionParserException (_("Attempt to read outside 
action buffer"));
+               }
                return m_buffer[off];
        }
 
@@ -94,39 +93,52 @@
        ///
        const char* read_string(size_t pc) const
        {
-               //assert(pc < m_buffer.size() );
-               return (const char*)(&m_buffer[pc]);
+               assert(pc < m_buffer.size() );
+               return reinterpret_cast<const char*>(&m_buffer[pc]);
        }
 
        /// Get a variable length 32-bit integer from the stream.
        /// Store its length in the passed boost::uint8_t.
        boost::uint32_t read_V32(size_t pc, boost::uint8_t& length) const
        {
-               boost::uint32_t res = m_buffer.at(pc);
+           const size_t buflen = m_buffer.size();
+           const std::string err = _("Attempt to read outside action buffer");
+           
+           if (pc >= buflen) throw ActionParserException(err);
+
+               boost::uint32_t res = m_buffer[pc];
                if (!(res & 0x00000080))
                {
                        length = 1;
                        return res;
                }
-               res = (res & 0x0000007F) | (m_buffer.at(pc + 1) << 7);
+
+           if (pc + 1 >= buflen) throw ActionParserException(err);
+               res = (res & 0x0000007F) | (m_buffer[pc + 1] << 7);
                if (!(res & 0x00004000))
                {
                        length = 2;
                        return res;
                }
-               res = (res & 0x00003FFF) | (m_buffer.at(pc + 2) << 14);
+
+           if (pc + 2 >= buflen) throw ActionParserException(err);
+               res = (res & 0x00003FFF) | (m_buffer[pc + 2] << 14);
                if (!(res & 0x00200000))
                {
                        length = 3;
                        return res;
                }
-               res = (res & 0x001FFFFF) | (m_buffer.at(pc + 3) << 21);
+
+           if (pc + 3 >= buflen) throw ActionParserException(err);
+               res = (res & 0x001FFFFF) | (m_buffer[pc + 3] << 21);
                if (!(res & 0x10000000))
                {
                        length = 4;
                        return res;
                }
-               res = (res & 0x0FFFFFFF) | (m_buffer.at(pc + 4) << 28);
+
+           if (pc + 4 >= buflen) throw ActionParserException(err);
+               res = (res & 0x0FFFFFFF) | (m_buffer[pc + 4] << 28);
                length = 5;
                return res;
        }
@@ -134,6 +146,7 @@
     /// Get a pointer to the current instruction within the code
        const unsigned char* getFramePointer(size_t pc) const
        {
+           assert (pc < m_buffer.size());
                return reinterpret_cast<const unsigned char*>(&m_buffer.at(pc));
        }
 
@@ -145,8 +158,8 @@
 
        const unsigned char* get_buffer(size_t pc) const
        {
-               //assert(pc < m_buffer.size() );
-               return (const unsigned char*)(&m_buffer.at(pc));
+               assert(pc < m_buffer.size() );
+               return reinterpret_cast<const unsigned char*>(&m_buffer[pc]);
        }
 
        /// Get a signed integer value from given offset
@@ -155,14 +168,15 @@
        ///
        boost::int16_t read_int16(size_t pc) const
        {
-               boost::int16_t ret = (m_buffer.at(pc) | (m_buffer.at(pc + 1) << 
8));
+           if (pc + 1 >= m_buffer.size()) {
+               throw ActionParserException(_("Attempt to read outside action 
buffer limits"));
+           }
+               boost::int16_t ret = (m_buffer[pc] | (m_buffer[pc + 1] << 8));
                return ret;
        }
 
        /// Get an unsigned short integer value from given offset
-       //
-       /// Useful to hide complexity of underlying buffer access.
-       ///
+    /// read_int16 should check buffer boundaries.
        boost::uint16_t read_uint16(size_t pc) const
        {
                return static_cast<boost::uint16_t>(read_int16(pc));
@@ -174,10 +188,14 @@
        ///
        boost::int32_t read_int32(size_t pc) const
        {
+               if (pc + 3 >= m_buffer.size()) {
+               throw ActionParserException(_("Attempt to read outside action 
buffer limits"));
+           }
+           
                boost::int32_t  val = m_buffer[pc]
-                     | (m_buffer.at(pc + 1) << 8)
-                     | (m_buffer.at(pc + 2) << 16)
-                     | (m_buffer.at(pc + 3) << 24);
+                     | (m_buffer[pc + 1] << 8)
+                     | (m_buffer[pc + 2] << 16)
+                     | (m_buffer[pc + 3] << 24);
                return val;
        }
 
@@ -203,7 +221,8 @@
        /// Return a value from the constant pool
        const char* dictionary_get(size_t n) const
        {
-               return m_dictionary.at(n);
+           assert (n < m_dictionary.size());
+               return m_dictionary[n];
        }
 
        /// Interpret the SWF::ACTION_CONSTANTPOOL opcode. 

Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.235
retrieving revision 1.236
diff -u -b -r1.235 -r1.236
--- server/vm/ASHandlers.cpp    6 May 2008 16:26:13 -0000       1.235
+++ server/vm/ASHandlers.cpp    7 May 2008 09:41:14 -0000       1.236
@@ -451,7 +451,12 @@
 //    GNASH_REPORT_FUNCTION;
 //     It is very heavy operation
 //     if ( _handlers[type].getName() == "unsupported" ) return false;
+    try {
        get_handlers()[type].execute(thread);
+       }
+       catch (ActionParserException& e) {
+           log_swferror(_("Malformed action code: %s"), e.what());
+       }
 }
 
 void

Index: server/vm/action.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/action.cpp,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- server/vm/action.cpp        16 Apr 2008 15:43:34 -0000      1.36
+++ server/vm/action.cpp        7 May 2008 09:41:14 -0000       1.37
@@ -97,14 +97,14 @@
                                method.to_debug_string().c_str());
                        buf[255] = '\0';
                
-                       throw ActionException(buf);
+                       throw ActionTypeError(buf);
                }
        }
-       catch (ActionException& ex)
+       catch (ActionTypeError& e)
        {
                assert(val.is_undefined());
                IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror("%s", ex.what());
+               log_aserror("%s", e.what());
                );
        }
 




reply via email to

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