Blob Blame History Raw
diff -ur js-1.8.5.orig/js/src/jsarray.cpp js-1.8.5/js/src/jsarray.cpp
--- js-1.8.5.orig/js/src/jsarray.cpp	2011-03-31 23:08:36.000000000 +0400
+++ js-1.8.5/js/src/jsarray.cpp	2015-04-15 01:10:10.662544828 +0300
@@ -1223,8 +1223,6 @@
 array_toString_sub(JSContext *cx, JSObject *obj, JSBool locale,
                    JSString *sepstr, Value *rval)
 {
-    JS_CHECK_RECURSION(cx, return false);
-
     /* Get characters to use for the separator. */
     static const jschar comma = ',';
     const jschar *sep;
@@ -1323,6 +1321,8 @@
 static JSBool
 array_toString(JSContext *cx, uintN argc, Value *vp)
 {
+    JS_CHECK_RECURSION(cx, return false);
+
     JSObject *obj = ToObject(cx, &vp[1]);
     if (!obj)
         return false;
@@ -1357,6 +1357,8 @@
 static JSBool
 array_toLocaleString(JSContext *cx, uintN argc, Value *vp)
 {
+    JS_CHECK_RECURSION(cx, return false);
+
     JSObject *obj = ToObject(cx, &vp[1]);
     if (!obj)
         return false;
@@ -1454,6 +1456,8 @@
 static JSBool
 array_join(JSContext *cx, uintN argc, Value *vp)
 {
+    JS_CHECK_RECURSION(cx, return false);
+
     JSString *str;
     if (argc == 0 || vp[2].isUndefined()) {
         str = NULL;
diff --git a/js/src/tests/ecma_5/extensions/array-toString-recursion.js b/js/src/tests/ecma_5/extensions/array-toString-recursion.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/array-toString-recursion.js
@@ -0,0 +1,46 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 635389;
+var summary = 'Infinite recursion via [].{toString,toLocaleString,join}';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+  var x = [];
+  x.join = Array.prototype.toString;
+  "" + x;
+  throw new Error("should have thrown");
+}
+catch (e)
+{
+  assertEq(e instanceof InternalError, true,
+           "should have thrown for over-recursion");
+}
+
+try
+{
+  var x = { toString: Array.prototype.toString, join: Array.prototype.toString };
+  "" + x;
+  throw new Error("should have thrown");
+}
+catch (e)
+{
+  assertEq(e instanceof InternalError, true,
+           "should have thrown for over-recursion");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
+
+print("All tests passed!");
diff -ur js-1.8.5.orig/js/src/tests/ecma_5/extensions/jstests.list js-1.8.5/js/src/tests/ecma_5/extensions/jstests.list
--- js-1.8.5.orig/js/src/tests/ecma_5/extensions/jstests.list	2011-03-31 23:08:36.000000000 +0400
+++ js-1.8.5/js/src/tests/ecma_5/extensions/jstests.list	2015-04-15 01:15:08.784740028 +0300
@@ -9,6 +9,7 @@
 script bug472534.js
 script bug496985.js
 script bug566661.js
+script array-toString-recursion.js
 script eval-native-callback-is-indirect.js
 script extension-methods-reject-null-undefined-this.js
 skip-if(!xulRuntime.shell) script function-definition-with.js # needs evaluate()