Merged patches from Harri Porten and David Faure to fix:
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Dec 2003 10:11:47 +0000 (10:11 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Dec 2003 10:11:47 +0000 (10:11 +0000)
<rdar://problem/3497643>: reproducible crash printing self-referential array

* kjs/array_object.cpp:
        (ArrayProtoFuncImp::call): Break out of the loop if an exception was thrown.
        * kjs/nodes.cpp:
        (FunctionCallNode::evaluate): Move function call depth check from here...
        * kjs/object.cpp:
        (KJS::Object::call): ...to here.
        * kjs/object.h: Un-inline Object::call now that it does more.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@5645 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/array_object.cpp
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/object.cpp
JavaScriptCore/kjs/object.h

index 37b100e..3d51dcb 100644 (file)
@@ -1,3 +1,17 @@
+2003-12-02  Maciej Stachowiak  <mjs@apple.com>
+
+        Merged patches from Harri Porten and David Faure to fix:
+
+       <rdar://problem/3497643>: reproducible crash printing self-referential array
+        
+       * kjs/array_object.cpp:
+        (ArrayProtoFuncImp::call): Break out of the loop if an exception was thrown.
+        * kjs/nodes.cpp:
+        (FunctionCallNode::evaluate): Move function call depth check from here...
+        * kjs/object.cpp:
+        (KJS::Object::call): ...to here.
+        * kjs/object.h: Un-inline Object::call now that it does more.
+
 2003-12-01  Richard Williamson   <rjw@apple.com>
 
        Fixed mistake in method signatures used to get boolean and integer fields.
index c4a0bae..904ea38 100644 (file)
@@ -469,6 +469,8 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
       Value element = thisObj.get(exec,k);
       if (element.type() != UndefinedType && element.type() != NullType)
         str += element.toString(exec);
+      if ( exec->hadException() )
+       break;
     }
     result = String(str);
     break;
index 6c18f84..65da755 100644 (file)
@@ -698,14 +698,6 @@ Value FunctionCallNode::evaluate(ExecState *exec)
     return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, expr);
   }
 
-#if KJS_MAX_STACK > 0
-  static int depth = 0; // sum of all concurrent interpreters
-  if (++depth > KJS_MAX_STACK) {
-    --depth;
-    return throwError(exec, RangeError, "Exceeded maximum function call depth calling %s (result of expression %s).", v, expr);
-  }
-#endif
-
   Value thisVal;
   if (ref.isMutable())
     thisVal = ref.getBase(exec);
@@ -730,10 +722,6 @@ Value FunctionCallNode::evaluate(ExecState *exec)
   Object thisObj = Object::dynamicCast(thisVal);
   Value result = func.call(exec,thisObj, argList);
 
-#if KJS_MAX_STACK > 0
-  --depth;
-#endif
-
   return result;
 }
 
index bd2c6d6..8e0093e 100644 (file)
@@ -51,6 +51,29 @@ Object Object::dynamicCast(const Value &v)
   return Object(static_cast<ObjectImp*>(v.imp()));
 }
 
+
+Value Object::call(ExecState *exec, Object &thisObj, const List &args)
+{ 
+#if KJS_MAX_STACK > 0
+  static int depth = 0; // sum of all concurrent interpreters
+  if (++depth > KJS_MAX_STACK) {
+    --depth;
+    Object err = Error::create(exec, RangeError,
+                               "Maximum call stack size exceeded.");
+    exec->setException(err);
+    return err;
+  }
+#endif
+
+  Value ret = imp()->call(exec,thisObj,args); 
+
+#if KJS_MAX_STACK > 0
+  --depth;
+#endif
+
+  return ret;
+}
+
 // ------------------------------ ObjectImp ------------------------------------
 
 ObjectImp::ObjectImp(const Object &proto)
index 0e382be..9d312c7 100644 (file)
@@ -698,9 +698,6 @@ namespace KJS {
   inline bool Object::implementsCall() const
     { return imp()->implementsCall(); }
 
-  inline Value Object::call(ExecState *exec, Object &thisObj, const List &args)
-    { return imp()->call(exec,thisObj,args); }
-
   inline bool Object::implementsHasInstance() const
     { return imp()->implementsHasInstance(); }