Bug 1519142 - Handle cyclic [[Protototype]] chains in two places. r=jorendorff
authorTom Schuster <evilpies@gmail.com>
Tue, 15 Jan 2019 17:24:47 +0000
changeset 511090 9fb6d716ad11c8c471e55a58daef61a8b8b671b1
parent 511089 b37c6861572aa51891365a15e94cb8bab5940d7a
child 511091 7477e57523cdfe89a60b1ce8d38b713f576d3212
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1519142
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1519142 - Handle cyclic [[Protototype]] chains in two places. r=jorendorff Differential Revision: https://phabricator.services.mozilla.com/D16387
js/src/jit-test/tests/proxy/getPrototype-cycle-for-in.js
js/src/jit-test/tests/proxy/getPrototype-cycle-hasInstance.js
js/src/vm/Iteration.cpp
js/src/vm/JSObject.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/proxy/getPrototype-cycle-for-in.js
@@ -0,0 +1,12 @@
+// |jit-test| exitstatus: 6
+timeout(0.5);
+
+var proxy = new Proxy({}, {
+    getPrototypeOf() {
+        return proxy;
+    }
+});
+
+var obj = {a: 1, b: 2, __proto__: proxy};
+for (var x in obj) {}
+assertEq(0, 1); // Should timeout.
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/proxy/getPrototype-cycle-hasInstance.js
@@ -0,0 +1,11 @@
+// |jit-test| exitstatus: 6
+timeout(0.5)
+
+var proxy = new Proxy({}, {
+    getPrototypeOf() {
+        return proxy;
+    }
+});
+
+var x = proxy instanceof function() {};
+assertEq(0, 1); // Should timeout.
--- a/js/src/vm/Iteration.cpp
+++ b/js/src/vm/Iteration.cpp
@@ -537,16 +537,20 @@ static bool Snapshot(JSContext* cx, Hand
     if (flags & JSITER_OWNONLY) {
       break;
     }
 
     if (!GetPrototype(cx, pobj, &pobj)) {
       return false;
     }
 
+    // The [[Prototype]] chain might be cyclic.
+    if (!CheckForInterrupt(cx)) {
+      return false;
+    }
   } while (pobj != nullptr);
 
 #ifdef JS_MORE_DETERMINISTIC
 
   /*
    * In some cases the enumeration order for an object depends on the
    * execution mode (interpreter vs. JIT), especially for native objects
    * with a class enumerate hook (where resolving a property changes the
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -3395,16 +3395,20 @@ bool js::ToPropertyKeySlow(JSContext* cx
 }
 
 /* * */
 
 bool js::IsPrototypeOf(JSContext* cx, HandleObject protoObj, JSObject* obj,
                        bool* result) {
   RootedObject obj2(cx, obj);
   for (;;) {
+    // The [[Prototype]] chain might be cyclic.
+    if (!CheckForInterrupt(cx)) {
+      return false;
+    }
     if (!GetPrototype(cx, obj2, &obj2)) {
       return false;
     }
     if (!obj2) {
       *result = false;
       return true;
     }
     if (obj2 == protoObj) {