Title: [205732] releases/WebKitGTK/webkit-2.14
Revision
205732
Author
[email protected]
Date
2016-09-09 03:35:22 -0700 (Fri, 09 Sep 2016)

Log Message

Merge r205535 - ProxyObject's structure should not have ObjectPrototype as its prototype and it should not have special behavior for intercepting "__proto__"
https://bugs.webkit.org/show_bug.cgi?id=161558

Reviewed by Benjamin Poulain.

JSTests:

* stress/proxy-get-prototype-of.js:
* stress/proxy-set-prototype-of.js:
(let.handler.setPrototypeOf): Deleted.
* stress/proxy-underscore-proto.js: Added.
(assert):

Source/_javascript_Core:

ProxyObject had ObjectPrototype as its direct prototype.
This could lead to infinite loops when doing a getDirectPrototype()
loop.

Fixing this bug revealed another bug, which I made when implementing Proxy.
We should not special case "__proto__" in get and set for Proxy Object's
hooks. "__proto__" should just go through the normal set and get path.

* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/ProxyObject.cpp:
(JSC::performProxyGet):
(JSC::ProxyObject::put):

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog (205731 => 205732)


--- releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog	2016-09-09 10:15:32 UTC (rev 205731)
+++ releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog	2016-09-09 10:35:22 UTC (rev 205732)
@@ -1,5 +1,18 @@
 2016-09-06  Saam Barati  <[email protected]>
 
+        ProxyObject's structure should not have ObjectPrototype as its prototype and it should not have special behavior for intercepting "__proto__"
+        https://bugs.webkit.org/show_bug.cgi?id=161558
+
+        Reviewed by Benjamin Poulain.
+
+        * stress/proxy-get-prototype-of.js:
+        * stress/proxy-set-prototype-of.js:
+        (let.handler.setPrototypeOf): Deleted.
+        * stress/proxy-underscore-proto.js: Added.
+        (assert):
+
+2016-09-06  Saam Barati  <[email protected]>
+
         Make JSMap and JSSet faster
         https://bugs.webkit.org/show_bug.cgi?id=160989
 

Added: releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-dont-infinite-loop.js (0 => 205732)


--- releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-dont-infinite-loop.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-dont-infinite-loop.js	2016-09-09 10:35:22 UTC (rev 205732)
@@ -0,0 +1,17 @@
+function foo() {
+    let target = {
+      __proto__: null
+    };
+    let proxy = new Proxy(target, {
+        get(...args) {
+            return Reflect.get(...args);
+        }
+    });
+    Object.prototype.__proto__ = {
+       __proto__: proxy,
+    };
+
+    let a = {};
+    a.test;
+}
+foo();

Modified: releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-get-prototype-of.js (205731 => 205732)


--- releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-get-prototype-of.js	2016-09-09 10:15:32 UTC (rev 205731)
+++ releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-get-prototype-of.js	2016-09-09 10:35:22 UTC (rev 205732)
@@ -18,7 +18,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let threw = false;
@@ -48,7 +47,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let threw = false;
@@ -83,7 +81,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let threw = false;
@@ -109,7 +106,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let threw = false;
@@ -137,7 +133,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let threw = false;
@@ -165,7 +160,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let threw = false;
@@ -194,7 +188,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let threw = false;
@@ -224,7 +217,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let threw = false;
@@ -255,7 +247,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let result = get();
@@ -285,7 +276,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             let result = get();
@@ -308,7 +298,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             assert(get() === proto);
@@ -333,7 +322,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             assert(get() === proto);
@@ -360,7 +348,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             assert(get() === proto);
@@ -387,7 +374,6 @@
         let getters = [
             () => Reflect.getPrototypeOf(proxy),
             () => Object.getPrototypeOf(proxy),
-            () => proxy.__proto__,
         ];
         for (let get of getters) {
             assert(get() === proto);

Modified: releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-set-prototype-of.js (205731 => 205732)


--- releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-set-prototype-of.js	2016-09-09 10:15:32 UTC (rev 205731)
+++ releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-set-prototype-of.js	2016-09-09 10:35:22 UTC (rev 205732)
@@ -18,7 +18,6 @@
         let setters = [
             () => Reflect.setPrototypeOf(proxy, {}),
             () => Object.setPrototypeOf(proxy, {}),
-            () => proxy.__proto__ = {},
         ];
         for (let set of setters) {
             let threw = false;
@@ -48,7 +47,6 @@
         let setters = [
             () => Reflect.setPrototypeOf(proxy, {}),
             () => Object.setPrototypeOf(proxy, {}),
-            () => proxy.__proto__ = {},
         ];
         for (let set of setters) {
             let threw = false;
@@ -75,7 +73,6 @@
         let setters = [
             () => Reflect.setPrototypeOf(proxy, {}),
             () => Object.setPrototypeOf(proxy, {}),
-            () => proxy.__proto__ = {},
         ];
         for (let set of setters) {
             let threw = false;
@@ -104,15 +101,13 @@
         let setters = [
             () => Reflect.setPrototypeOf(proxy, {}),
             () => Object.setPrototypeOf(proxy, {}),
-            () => proxy.__proto__ = {},
         ];
         for (let set of setters) {
             let result = set();
             assert(result);
             assert(Reflect.getPrototypeOf(target) === null);
-            // FIXME: when we implement Proxy.[[GetPrototypeOf]] this should work.
-            //assert(Reflect.getPrototypeOf(proxy) === null);
-            //assert(proxy.__proto__ === null);
+            assert(Reflect.getPrototypeOf(proxy) === null);
+            assert(proxy.__proto__ === undefined);
         }
     }
 }
@@ -133,15 +128,13 @@
         let setters = [
             () => Reflect.setPrototypeOf(proxy, obj),
             () => Object.setPrototypeOf(proxy, obj),
-            () => proxy.__proto__ = obj,
         ];
         for (let set of setters) {
             let result = set();
             assert(result);
             assert(Reflect.getPrototypeOf(target) === obj);
-            // FIXME: when we implement Proxy.[[GetPrototypeOf]] this should work.
-            //assert(Reflect.getPrototypeOf(proxy) === obj);
-            //assert(proxy.__proto__ === obj);
+            assert(Reflect.getPrototypeOf(proxy) === obj);
+            assert(proxy.__proto__ === obj);
         }
     }
 }
@@ -167,7 +160,6 @@
         let setters = [
             () => Reflect.setPrototypeOf(proxy, obj),
             () => Object.setPrototypeOf(proxy, obj),
-            () => proxy.__proto__ = obj,
         ];
         for (let set of setters) {
             let threw = false;
@@ -182,9 +174,8 @@
 
             assert(threw);
             assert(Reflect.getPrototypeOf(target) === null);
-            // FIXME: when we implement Proxy.[[GetPrototypeOf]] this should work.
-            //assert(Reflect.getPrototypeOf(proxy) === null);
-            //assert(proxy.__proto__ === null);
+            assert(Reflect.getPrototypeOf(proxy) === null);
+            assert(proxy.__proto__ === undefined);
         }
     }
 }
@@ -209,7 +200,6 @@
         let setters = [
             [() => Reflect.setPrototypeOf(proxy, null), true],
             [() => Object.setPrototypeOf(proxy, null), proxy],
-            [() => proxy.__proto__ = null, null]
         ];
         for (let [set, expectedResult] of setters) {
             let result = set();
@@ -217,9 +207,8 @@
             assert(called);
             called = false;
             assert(Reflect.getPrototypeOf(target) === null);
-            // FIXME: when we implement Proxy.[[GetPrototypeOf]] this should work.
-            //assert(Reflect.getPrototypeOf(proxy) === null);
-            //assert(proxy.__proto__ === null);
+            assert(Reflect.getPrototypeOf(proxy) === null);
+            assert(proxy.__proto__ === undefined);
         }
     }
 }
@@ -245,7 +234,6 @@
         let setters = [
             [() => Reflect.setPrototypeOf(proxy, obj), true],
             [() => Object.setPrototypeOf(proxy, obj), proxy],
-            [() => proxy.__proto__ = obj, obj]
         ];
         for (let [set, expectedResult] of setters) {
             let result = set();
@@ -253,9 +241,8 @@
             assert(called);
             called = false;
             assert(Reflect.getPrototypeOf(target) === obj);
-            // FIXME: when we implement Proxy.[[GetPrototypeOf]] this should work.
-            //assert(Reflect.getPrototypeOf(proxy) === null);
-            //assert(proxy.__proto__ === null);
+            assert(Reflect.getPrototypeOf(proxy) === obj);
+            assert(proxy.__proto__ === obj);
         }
     }
 }
@@ -283,9 +270,8 @@
 
         assert(threw);
         assert(Reflect.getPrototypeOf(target) === null);
-        // FIXME: when we implement Proxy.[[GetPrototypeOf]] this should work.
-        //assert(Reflect.getPrototypeOf(proxy) === null);
-        //assert(proxy.__proto__ === null);
+        assert(Reflect.getPrototypeOf(proxy) === null);
+        assert(proxy.__proto__ === undefined);
     }
 }
 
@@ -293,36 +279,7 @@
     let target = {};
     target.__proto__ = null;
     Reflect.preventExtensions(target);
-    let handler = {
-        setPrototypeOf: function(theTarget, value) {
-            return Reflect.setPrototypeOf(theTarget, value);
-        }
-    };
-    
-    let proxy = new Proxy(target, handler);
-    for (let i = 0; i < 500; i++) {
-        let obj = {};
-        let threw = false;
-        try {
-            proxy.__proto__ = obj;
-        } catch(e) {
-            threw = true;
-            assert(e.toString() === "TypeError: Proxy 'setPrototypeOf' returned false indicating it could not set the prototype value. The operation was expected to succeed");
-        }
 
-        assert(threw);
-        assert(Reflect.getPrototypeOf(target) === null);
-        // FIXME: when we implement Proxy.[[GetPrototypeOf]] this should work.
-        //assert(Reflect.getPrototypeOf(proxy) === null);
-        //assert(proxy.__proto__ === null);
-    }
-}
-
-{
-    let target = {};
-    target.__proto__ = null;
-    Reflect.preventExtensions(target);
-
     let called = false;
     let handler = {
         setPrototypeOf: function(theTarget, value) {
@@ -339,9 +296,8 @@
 
         assert(called);
         called = false;
-        // FIXME: when we implement Proxy.[[GetPrototypeOf]] this should work.
-        //assert(Reflect.getPrototypeOf(proxy) === null);
-        //assert(proxy.__proto__ === null);
+        assert(Reflect.getPrototypeOf(proxy) === null);
+        assert(proxy.__proto__ === undefined);
     }
 }
 
@@ -366,9 +322,8 @@
         assert(called);
         called = false;
 
-        // FIXME: when we implement Proxy.[[GetPrototypeOf]] this should work.
-        //assert(Reflect.getPrototypeOf(proxy) === null);
-        //assert(proxy.__proto__ === null);
+        assert(Reflect.getPrototypeOf(proxy) === null);
+        assert(proxy.__proto__ === undefined);
     }
 }
 

Added: releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-underscore-proto.js (0 => 205732)


--- releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-underscore-proto.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-underscore-proto.js	2016-09-09 10:35:22 UTC (rev 205732)
@@ -0,0 +1,110 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad assertion!");
+}
+
+{
+    let p = {};
+    let target = {__proto__: p};
+    let called = false;
+    let handler = {
+        get(target, key, receiver) {
+            called = true;
+            assert(key === "__proto__");
+            return target[key];
+        },
+
+        getPrototypeOf() {
+            assert(false);
+        }
+    };
+    
+    let proxy = new Proxy(target, handler);
+    for (let i = 0; i < 500; i++) {
+        assert(proxy.__proto__ === p);
+        assert(called);
+        called = false;
+    }
+}
+
+{
+    let p = {};
+    let target = {__proto__: p};
+    let called1 = false;
+    let called2 = false;
+    let handler = {
+        get(target, key, receiver) {
+            called1 = true;
+            assert(key === "__proto__");
+            return Reflect.get(target, key, receiver);
+        },
+
+        getPrototypeOf(...args) {
+            called2 = true;
+            return Reflect.getPrototypeOf(...args);
+        }
+    };
+    
+    let proxy = new Proxy(target, handler);
+    for (let i = 0; i < 500; i++) {
+        assert(proxy.__proto__ === p);
+        assert(called1);
+        assert(called2);
+        called1 = false;
+        called2 = false;
+    }
+}
+
+{
+    let p = {};
+    let target = {__proto__: null};
+    let called = false;
+    let handler = {
+        set(target, key, value, receiver) {
+            called = true;
+            assert(key === "__proto__");
+            return target[key] = value;
+        },
+
+        setPrototypeOf() {
+            assert(false);
+        }
+    };
+    
+    let proxy = new Proxy(target, handler);
+    for (let i = 0; i < 500; i++) {
+        proxy.__proto__ = p;
+        assert(proxy.__proto__ === p);
+        assert(target.__proto__ === p);
+        target.__proto__ = null;
+        assert(called);
+        called = false;
+    }
+}
+
+{
+    let p = {};
+    let target = {__proto__: null};
+    let called = false;
+    let handler = {
+        set(target, key, value, receiver) {
+            called = true;
+            assert(key === "__proto__");
+            return Reflect.set(target, key, value, receiver);
+        },
+
+        setPrototypeOf() {
+            assert(false);
+        }
+    };
+    
+    let proxy = new Proxy(target, handler);
+    for (let i = 0; i < 500; i++) {
+        proxy.__proto__ = p;
+        assert(proxy.__proto__ === p);
+        assert(target.__proto__ === p);
+        target.__proto__ = null;
+        assert(called);
+        called = false;
+    }
+}

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog (205731 => 205732)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog	2016-09-09 10:15:32 UTC (rev 205731)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog	2016-09-09 10:35:22 UTC (rev 205732)
@@ -1,5 +1,26 @@
 2016-09-06  Saam Barati  <[email protected]>
 
+        ProxyObject's structure should not have ObjectPrototype as its prototype and it should not have special behavior for intercepting "__proto__"
+        https://bugs.webkit.org/show_bug.cgi?id=161558
+
+        Reviewed by Benjamin Poulain.
+
+        ProxyObject had ObjectPrototype as its direct prototype.
+        This could lead to infinite loops when doing a getDirectPrototype()
+        loop.
+
+        Fixing this bug revealed another bug, which I made when implementing Proxy.
+        We should not special case "__proto__" in get and set for Proxy Object's
+        hooks. "__proto__" should just go through the normal set and get path.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/ProxyObject.cpp:
+        (JSC::performProxyGet):
+        (JSC::ProxyObject::put):
+
+2016-09-06  Saam Barati  <[email protected]>
+
         Member call on NULL pointer in _javascript_Core/dfg/DFGAbstractInterpretterInlines.h
         https://bugs.webkit.org/show_bug.cgi?id=160870
 

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSGlobalObject.cpp (205731 => 205732)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2016-09-09 10:15:32 UTC (rev 205731)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2016-09-09 10:35:22 UTC (rev 205732)
@@ -508,9 +508,9 @@
     m_moduleNamespaceObjectStructure.set(vm, this, JSModuleNamespaceObject::createStructure(vm, this, jsNull()));
     {
         bool isCallable = false;
-        m_proxyObjectStructure.set(vm, this, ProxyObject::createStructure(vm, this, m_objectPrototype.get(), isCallable));
+        m_proxyObjectStructure.set(vm, this, ProxyObject::createStructure(vm, this, jsNull(), isCallable));
         isCallable = true;
-        m_callableProxyObjectStructure.set(vm, this, ProxyObject::createStructure(vm, this, m_objectPrototype.get(), isCallable));
+        m_callableProxyObjectStructure.set(vm, this, ProxyObject::createStructure(vm, this, jsNull(), isCallable));
     }
     m_proxyRevokeStructure.set(vm, this, ProxyRevoke::createStructure(vm, this, m_functionPrototype.get()));
 

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/ProxyObject.cpp (205731 => 205732)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/ProxyObject.cpp	2016-09-09 10:15:32 UTC (rev 205731)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/ProxyObject.cpp	2016-09-09 10:35:22 UTC (rev 205732)
@@ -125,9 +125,6 @@
 
     JSObject* target = proxyObject->target();
 
-    if (propertyName == vm.propertyNames->underscoreProto)
-        return proxyObject->performGetPrototype(exec);
-
     auto performDefaultGet = [&] {
         return target->get(exec, propertyName);
     };
@@ -458,8 +455,6 @@
 {
     VM& vm = exec->vm();
     slot.disableCaching();
-    if (propertyName == vm.propertyNames->underscoreProto)
-        return Base::put(cell, exec, propertyName, value, slot);
 
     ProxyObject* thisObject = jsCast<ProxyObject*>(cell);
     auto performDefaultPut = [&] () {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to