[Top][All Lists]
[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());
);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog libbase/GnashException.h server...,
Benjamin Wolsey <=