CVSROOT: /sources/gnash Module name: gnash Changes by: Chad Musick <cmusick> 07/11/22 11:09:55
Modified files: . : ChangeLog server : as_environment.h as_object.cpp builtin_function.h swf_function.cpp server/vm : ASHandlers.cpp testsuite/swfdec: PASSING Log message: Fix limits executions -- be sure to increment call stack on functions, and to stop searching at some point up the object inheritance chain. 23 new passing tests. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4916&r2=1.4917 http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.h?cvsroot=gnash&r1=1.64&r2=1.65 http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.cpp?cvsroot=gnash&r1=1.84&r2=1.85 http://cvs.savannah.gnu.org/viewcvs/gnash/server/builtin_function.h?cvsroot=gnash&r1=1.12&r2=1.13 http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf_function.cpp?cvsroot=gnash&r1=1.41&r2=1.42 http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.158&r2=1.159 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/swfdec/PASSING?cvsroot=gnash&r1=1.64&r2=1.65 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.4916 retrieving revision 1.4917 diff -u -b -r1.4916 -r1.4917 --- ChangeLog 22 Nov 2007 08:04:47 -0000 1.4916 +++ ChangeLog 22 Nov 2007 11:09:53 -0000 1.4917 @@ -1,3 +1,16 @@ +2007-11-22 Chad Musick <[EMAIL PROTECTED]> + + * testsuite/swfdec/PASSING: 23 new passing tests. + * server/as_environment.h: Make pushCallFrame and popCallFrame + private, remove clearCallFrames(), provide FrameGuard nested + class to provide safe access. + * server/as_object.cpp: Prevent recursion in get_super, check for + search depth when finding properties and throw a limit exception, + * server/swf_function.cpp: Change to use as_environment::FrameGuard + and use it earlier. Only look for super in swf6+. + * server/builtin_function.h: Increase call stack on execution. + * server/vm/ASHandlers.cpp: Remove leftover debugging output. + 2007-11-22 Sandro Santilli <[EMAIL PROTECTED]> * testsuite/misc-ming.all/key_event_test.c: make the test more verbose Index: server/as_environment.h =================================================================== RCS file: /sources/gnash/gnash/server/as_environment.h,v retrieving revision 1.64 retrieving revision 1.65 diff -u -b -r1.64 -r1.65 --- server/as_environment.h 21 Nov 2007 09:21:49 -0000 1.64 +++ server/as_environment.h 22 Nov 2007 11:09:54 -0000 1.65 @@ -459,28 +459,16 @@ #endif // GNASH_USE_GC }; - /// Push a frame on the calls stack. - // - /// This should happen right before calling an ActionScript - /// function. Function local registers and variables - /// must be set *after* pushCallFrame has been invoked - /// - /// Call popCallFrame() at ActionScript function return. - /// - /// @param func - /// The function being called - /// - void pushCallFrame(as_function* func); - - /// Remove current call frame from the stack - // - /// This should happen when an ActionScript function returns. - /// - void popCallFrame() + /// A class to wrap frame access. Stack allocating a frame guard + /// will ensure that all CallFrame pushes have a corresponding + /// CallFrame pop, even in the presence of extraordinary returns. + class FrameGuard { - assert(!_localFrames.empty()); - _localFrames.pop_back(); - } + public: + FrameGuard(as_function* func) + { as_environment::pushCallFrame(func); } + ~FrameGuard() { as_environment::popCallFrame(); } + }; /// Get top element of the call stack // @@ -495,13 +483,6 @@ { return _localFrames.size(); } -/* - /// Clear the call stack - void clearCallFrames() - { - _localFrames.clear(); - } -*/ private: @@ -519,6 +500,29 @@ /// Movie target. character* _original_target; + /// Push a frame on the calls stack. + // + /// This should happen right before calling an ActionScript + /// function. Function local registers and variables + /// must be set *after* pushCallFrame has been invoked + /// + /// Call popCallFrame() at ActionScript function return. + /// + /// @param func + /// The function being called + /// + static void pushCallFrame(as_function* func); + + /// Remove current call frame from the stack + // + /// This should happen when an ActionScript function returns. + /// + static void popCallFrame() + { + assert(!_localFrames.empty()); + _localFrames.pop_back(); + } + /// Return the (possibly UNDEFINED) value of the named variable. // /// @param varname Index: server/as_object.cpp =================================================================== RCS file: /sources/gnash/gnash/server/as_object.cpp,v retrieving revision 1.84 retrieving revision 1.85 diff -u -b -r1.84 -r1.85 --- server/as_object.cpp 21 Nov 2007 09:21:49 -0000 1.84 +++ server/as_object.cpp 22 Nov 2007 11:09:54 -0000 1.85 @@ -110,13 +110,17 @@ *val = prop->getValue(*this); return true; } + catch (ActionLimitException& exc) + { + log_error(_("Caught action limit.")); + throw; + } catch (ActionException& exc) { // TODO: check if this should be an 'as' error.. (log_aserror) log_error(_("Caught exception: %s"), exc.what()); return false; } - } Property* @@ -139,26 +143,58 @@ as_object* as_object::get_super() { + static bool getting = false; + as_object *owner = NULL; + + Property *p = NULL; + + if (getting) + return NULL; + + getting = true; + // Super is this.__proto__.__constructor__.prototype as_object *proto = get_prototype().get(); if (!proto) + { + getting = false; return NULL; + } - as_value ctor; - bool ret = proto->get_member(NSV::PROP_uuCONSTRUCTORuu, &ctor); - if (!ret) + // If an object is its own prototype, we stop looking. + if (proto == this) + { + getting = false; + return this; + } + + p = proto->findProperty(NSV::PROP_uuCONSTRUCTORuu, 0, &owner); + if (!p) + { + getting = false; return NULL; + } + as_value ctor = p->getValue(*owner); as_object *ctor_obj = ctor.to_object().get(); if (!ctor_obj) + { + getting = false; return NULL; + } - as_value ctor_proto; - ret = ctor_obj->get_member(NSV::PROP_PROTOTYPE, &ctor_proto); - if (!ret) + p = ctor_obj->findProperty(NSV::PROP_PROTOTYPE, 0, &owner); + if (!p) + { + getting = false; return NULL; + } + as_value ctor_proto = p->getValue(*owner); as_object *super = ctor_proto.to_object().get(); + + getting = false; + return super; } @@ -224,10 +260,15 @@ std::set<as_object*> visited; int swfVersion = _vm.getSWFVersion(); + int i = 0; boost::intrusive_ptr<as_object> obj = this; while (obj && visited.insert(obj.get()).second) { + ++i; + if ((i > 255 && swfVersion == 5) || i > 257) + throw ActionLimitException("Lookup depth exceeded."); + Property* prop = obj->_members.getProperty(key); if (prop && prop->isVisible(swfVersion) ) { @@ -258,25 +299,25 @@ // don't enter an infinite loop looking for __proto__ ... if (key == NSV::PROP_uuPROTOuu) return NULL; - // this set will keep track of visited objects, - // to avoid infinite loops - std::set< as_object* > visited; + std::set<as_object*> visited; visited.insert(this); + int i = 0; + boost::intrusive_ptr<as_object> obj = get_prototype(); - while ( obj && visited.insert(obj.get()).second ) + while (obj && visited.insert(obj.get()).second) { - Property* prop = obj->_members.getProperty(key, nsname); - if ( prop && ( prop->isGetterSetter() || prop->isStatic() ) && prop->isVisible(swfVersion) ) + ++i; + if ((i > 255 && swfVersion == 5) || i > 257) + throw ActionLimitException("Property lookup depth exceeded."); + + Property* p = obj->_members.getProperty(key, nsname); + if (p && (p->isGetterSetter() | p->isStatic()) && p->isVisible(swfVersion)) { - // what if a property is found which is - // NOT a getter/setter ? - return prop; + return p; // What should we do if this is not a getter/setter ? } obj = obj->get_prototype(); } - - // No Getter/Setter or Static property found in inheritance chain return NULL; } @@ -521,8 +562,6 @@ if (std::find(mInterfaces.begin(), mInterfaces.end(), obj) == mInterfaces.end()) mInterfaces.push_back(obj); - else - fprintf(stderr, "Not adding duplicate interface.\n"); } bool @@ -817,7 +856,7 @@ int swfVersion = _vm.getSWFVersion(); - boost::intrusive_ptr<as_object> nullRet; + boost::intrusive_ptr<as_object> nullRet = NULL; Property* prop = _members.getProperty(key); if ( ! prop ) return nullRet; Index: server/builtin_function.h =================================================================== RCS file: /sources/gnash/gnash/server/builtin_function.h,v retrieving revision 1.12 retrieving revision 1.13 diff -u -b -r1.12 -r1.13 --- server/builtin_function.h 28 Sep 2007 10:10:36 -0000 1.12 +++ server/builtin_function.h 22 Nov 2007 11:09:54 -0000 1.13 @@ -23,6 +23,7 @@ #endif #include "as_function.h" // for inheritance +#include "as_environment.h" // for FrameGuard #include <cassert> @@ -77,6 +78,7 @@ /// Invoke this function or this Class constructor virtual as_value operator()(const fn_call& fn) { + as_environment::FrameGuard guard(this); assert(_func); return _func(fn); } Index: server/swf_function.cpp =================================================================== RCS file: /sources/gnash/gnash/server/swf_function.cpp,v retrieving revision 1.41 retrieving revision 1.42 diff -u -b -r1.41 -r1.42 --- server/swf_function.cpp 21 Nov 2007 09:21:49 -0000 1.41 +++ server/swf_function.cpp 22 Nov 2007 11:09:54 -0000 1.42 @@ -91,28 +91,12 @@ } -namespace { -class FrameGuard -{ -public: - FrameGuard(as_environment& env, swf_function *func) : mEnv(env) - { - env.pushCallFrame(func); - } - - ~FrameGuard() - { - mEnv.popCallFrame(); - } - - as_environment& mEnv; -}; -} // end of anonymous namespace - // Dispatch. as_value swf_function::operator()(const fn_call& fn) { + // Set up local stack frame, for parameters and locals. + as_environment::FrameGuard guard(this); as_environment* our_env = m_env; assert(our_env); @@ -128,16 +112,14 @@ log_msg("swf_function() stack:\n"); fn.env().dump_stack(); log_msg(" first_arg_bottom_index: %d\n", fn.first_arg_bottom_index); #endif - - assert(fn.this_ptr); - as_object *super = fn.this_ptr->get_super(); - - // Some features are version-dependant + // Some features are version-dependant. unsigned swfversion = VM::get().getSWFVersion(); - - // Set up local stack frame, for parameters and locals. - FrameGuard guard(*our_env, this); -// our_env->pushCallFrame(this); + assert(fn.this_ptr); + as_object *super = NULL; + if (swfversion > 5) + { + super = fn.this_ptr->get_super(); + } if (m_is_function2 == false) { @@ -275,7 +257,6 @@ } } - as_value result; // Execute the actions. Index: server/vm/ASHandlers.cpp =================================================================== RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v retrieving revision 1.158 retrieving revision 1.159 diff -u -b -r1.158 -r1.159 --- server/vm/ASHandlers.cpp 21 Nov 2007 22:35:37 -0000 1.158 +++ server/vm/ASHandlers.cpp 22 Nov 2007 11:09:54 -0000 1.159 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: ASHandlers.cpp,v 1.158 2007/11/21 22:35:37 strk Exp $ */ +/* $Id: ASHandlers.cpp,v 1.159 2007/11/22 11:09:54 cmusick Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -170,7 +170,6 @@ void ActionHandler::execute(ActionExec& thread) const { -// GNASH_REPORT_FUNCTION; return _callback(thread); } @@ -1394,12 +1393,10 @@ env.drop(1); if (instance->instanceOf(super)) { - fprintf(stderr, "Cast succeeded.\n"); env.top(0) = as_value(instance); } else { - fprintf(stderr, "Cast failed.\n"); env.top(0).set_null(); // null, not undefined. } @@ -3058,7 +3055,8 @@ if (obj) { - thread.setObjectMember(*obj, member_name, member_value); + thread.setObjectMember(*(obj.get()), member_name, member_value); + IF_VERBOSE_ACTION ( log_action(_("-- set_member %s.%s=%s"), env.top(2).to_debug_string().c_str(), Index: testsuite/swfdec/PASSING =================================================================== RCS file: /sources/gnash/gnash/testsuite/swfdec/PASSING,v retrieving revision 1.64 retrieving revision 1.65 diff -u -b -r1.64 -r1.65 --- testsuite/swfdec/PASSING 21 Nov 2007 21:57:51 -0000 1.64 +++ testsuite/swfdec/PASSING 22 Nov 2007 11:09:55 -0000 1.65 @@ -33,6 +33,7 @@ asbroadcaster-listeners-7.swf:38726a7a2f22b604c02c6c4bee4c0bd7 asbroadcaster-listeners-8.swf:7daa180ce19d8c4e4dcb17051908e12b asbroadcaster-override-5.swf:1a3dacf6579b150773097362b546ee7e +assetuperror-5.swf:81e05c01c883d200052546a7abfb7ad8 atan2-5.swf:64be2dd80026448ba20e798dc9b761e0 atan2-6.swf:090d94fe78d2fec52ac41786494979aa atan2-7.swf:b4b0629233685ed5e518e5bf237bf413 @@ -40,10 +41,13 @@ attachmovie-object-5.swf:a1fa0db4e7ac649e5451ff5e96a71436 attachmovie-object-6.swf:52c0c8d46a3535c7db79d3d827b31b41 attachmovie-object-7.swf:9a18445affc4ae1dc0e0fe085b13f1e1 +bevel-filter-properties-5.swf:0ec31af3035594a9cbcb1ba8a645ad4c +bitmap-filter-properties-5.swf:62973bfcdf9f1fd383440fabcbfebca9 bitwise-5.swf:98475055aae4796a066e7728d5a7a944 bitwise-6.swf:ef818f643cc14a4cc57248473e05a48c bitwise-7.swf:c18505cd0d075c512d15b6d96ab221d0 bitwise-8.swf:a99b312eddd076f8b9df649bc4b33964 +blur-filter-properties-5.swf:4c29ecc04df379ced45039fdbb79eb9c call-arguments-5.swf:422c391a2abd3e864eb8ed8a1e05ad31 callfunction-stack.swf:21d0c957f4caf0eb0ccd0dcadaf17500 case1-6.swf:ba805f628a3a2d1bbd292ec1e56d1708 @@ -59,10 +63,12 @@ clonesprite-depths-7.swf:c70968c65e52392d9c61470d0d698394 clonesprite-depths-8.swf:af472e7f31b31e886ca86430fb71106f color-getters.swf:4cee4418f75171e7bf423759a468b36b +color-matrix-filter-properties-5.swf:2349ffbd77298b0dea59d6ed618c382b color-new.swf:b19cf3d46f416b919eb312da473b6756 color-setRGB.swf:0841414e9ac7d2f9b57e40aec3d2f44f color-setTransform-empty.swf:2a72a5273ab8713ee289ff1726b0959c color-setTransform-negative.swf:0bc0510c35fc5c82de31b0db887fe535 +color-transform-properties-5.swf:74bd1e74d40fd8741000366645b7c776 color1.swf:3cc52a41193d342cfdfaeffe56edc3db comparisons-4.swf:e0bb89e492f3f35e51b1beb190935a14 comparisons-5.swf:d4dfeb4ec80ec1f5a7390eb699e269ee @@ -77,6 +83,7 @@ constructor-madness-7.swf:616b5b2cfbed3f3703e1b774974d7f48 constructor-madness-8.swf:5357273baf6b66f6af0223cb1d13b144 constructor-prototype.swf:22505f0f8dd8440972a298110d697e3b +convolution-filter-properties-5.swf:96e15de475e31c328e201c152ffd2f42 crash-0.5.2-cvs-return-from-block-5.swf:4aab3181976e557d6e0457ff7e0a6403 crash-0.5.2-cvs-return-from-block-6.swf:c1c585c3c888f13d69f9646c0f2fb928 crash-0.5.2-cvs-return-from-block-7.swf:e09d75c52f6209e8f488fb50744e1435 @@ -124,9 +131,11 @@ delete-prototypes-6.swf:1734eb410cfe52dffb937d5c1c210a0f delete-prototypes-7.swf:5b01906b25bcc0fa0783b259d49a9348 delete-prototypes-8.swf:4ec22b5249be231984324ee407255d56 +displacement-map-filter-properties-5.swf:b0d6a60fa2f9eee15163634c5a6c224f divide-7.swf:8b1d7b8cb6af31c83878774864c3900a doaction-after-placeobject.swf:ea4387286e602dd93cf2f75ea6698690 doaction-before-placeobject.swf:4e8f238ef804fe0d254cd9ed9581e097 +drop-shadow-filter-properties-5.swf:827a880fc55b1afb96515f0d64a064b6 duplicate-names-5.swf:d73096f662cf35b34c15e3f59fb88258 duplicate-names-6.swf:2f1c48973f13cb831bca9a4b7bbccde0 duplicate-names-7.swf:4bb8cb852ea9688c3964d8b5e2d3cf80 @@ -145,6 +154,8 @@ extends-constructors-7.swf:bdd4d88deef41da109379e5dc0c130d6 extends-constructors-8.swf:b812f8e472f897a73914d10101841b87 extends-simple.swf:5e3daf1e64d50b0c9ef06f7ad99f2bda +file-reference-list-properties-5.swf:4d13076bcc6ab1cd02fea9f62d4013cf +file-reference-properties-5.swf:238ae6d8bf7d0ee8a241f20cf1247e6e foreach-proto-simple-5.swf:63689d87c2e1eb1602b2624fa9a61c3e foreach-proto-simple-6.swf:6ef0541de231d2f6254bda0056d6c5db foreach-proto-simple-7.swf:08e9473a6b4d9ebb125a1d352a431b25 @@ -187,12 +198,15 @@ getvariable-length-5.swf:2d07e2afdf45356cf2df5c1176ed29ad getvariable-slashpath-5.swf:3067a6cdf4991af85520d7eb3bb51178 getvariable-special-5.swf:4baac55533a4cc67a3419dafb97cc888 +glow-filter-properties-5.swf:b3d05908aaa98c7115ec1727d695a16a goto1.swf:6f35a27cb3aee7f282eccb3b16290c70 goto2.swf:f845271dd90a84b3919ca9000d66cd25 goto3.swf:c9db121dc7744f6f76d4b6f6cdb9847f goto4.swf:cc19122dcb5d0c4d68bf7889822e4eb2 goto5.swf:cc19122dcb5d0c4d68bf7889822e4eb2 gotoframe.swf:2979edee317cb3e109ef769451b09616 +gradient-bevel-filter-properties-5.swf:4e4322654b7b7368fdc5499cff81654f +gradient-glow-filter-properties-5.swf:719ca44e28c6f4fd8ca97ed2c1386fdd height1.swf:245da260d32dbc48a5f38566ee70171b height3.swf:2b7547493377ae1c0163c8273a4073f7 height4.swf:8d36c180d196b49608f996db21a421bc @@ -337,11 +351,18 @@ place-object-remove-name-5.swf:74eed3173fee7eb8e21bfabb70ceb4c2 place-object-remove-name-6.swf:302e32a0834a50f219f8ab9a15234c41 place-object-remove-name-7.swf:689ff2c69386d51ce336691cb485ab55 +point-5.swf:9e49aa1df7118acccf003ae0648ef439 +point-properties-5.swf:c3439d59fa29fb709630ee3a3ad230b0 preload.swf:2fd2da9440e29289e83dadd1ed9c99c4 +print-job-init-5.swf:22889777e5e8230cee8c760c0930b5db property-native-5.swf:3609da1095cd97f5373da462b45ead1d prototype-addProperty-5.swf:1d9ac80542b3a9238ed09e78bdb8c563 prototype-propflags-5.swf:43f4ffa51653f54d0182610a01db8f1f prototype-propflags-8.swf:3c6f02bf6a3348879f3f50c28ee599cb +prototype-recursion-addProperty-5.swf:cb268cb74f2ebda340868ef624c02672 +prototype-recursion-get-6.swf:47fa73c88db1f3acedd832e2ddec6315 +prototype-recursion-get-7.swf:766d65bdfdb4a79073728607ce8dc0d3 +prototype-recursion-get-8.swf:9e1f31c39062dffaa99e9db4ca28838f prototypes.swf:21df8d7eda568fd27f19a56fec87a415 register-count.swf:861abb623a228e4152df92896ee807f0 registerclass-previous.swf:7ea3d590fa576190bda56996ff0fa768 @@ -504,7 +525,9 @@ tointeger-various-5.swf:25fab4b9f2e8739ac63863933a4c7ead tointeger-various-6.swf:71257f69e5f3feb6ae18ebf26ad2eb22 tointeger-various-7.swf:6251bc39b6449a82c89b6c821f9af0ff +totalframes.swf:cdc0d5e2017d293438ef80fa136c44e8 transform.swf:5c8533f9168ca3e92d000ce1693ed5ef +transform-properties-5.swf:b0386824584340e1d0a80f986ce779b9 try-throw-in-finally-6.swf:1c12d4b0f949704bd0794d73f0385007 try-throw-in-finally-7.swf:0342b214948d6bec886863f6f66cab33 try-throw-in-finally-8.swf:f5b7ae88f4383ebcdb8313674a2d85cb _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit