Title: [246346] trunk
Revision
246346
Author
[email protected]
Date
2019-06-11 20:18:53 -0700 (Tue, 11 Jun 2019)

Log Message

JSC should throw if proxy set returns falsish in strict mode context
https://bugs.webkit.org/show_bug.cgi?id=177398

Patch by Alexey Shvayka <[email protected]> on 2019-06-11
Reviewed by Yusuke Suzuki.

JSTests:

1. Add coverage for Proxy `set` trap returning falsy value in strict mode.
2. RegExp methods throw unless [[Set]] succeeds. Return `true` from Proxy `set` traps to fix the tests.

* stress/proxy-set.js: Add 2 test cases.
* stress/regexp-match-proxy.js: Fix test.
* stress/regexp-replace-proxy.js: Fix test.

Source/_javascript_Core:

Throw TypeError exception if Proxy's `set` trap returns falsy value.
(step 6.c of https://tc39.es/ecma262/#sec-putvalue)

* runtime/ProxyObject.cpp:
(JSC::ProxyObject::performPut):
(JSC::ProxyObject::put):
(JSC::ProxyObject::putByIndexCommon):
* runtime/ProxyObject.h:

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (246345 => 246346)


--- trunk/JSTests/ChangeLog	2019-06-12 03:18:25 UTC (rev 246345)
+++ trunk/JSTests/ChangeLog	2019-06-12 03:18:53 UTC (rev 246346)
@@ -1,5 +1,19 @@
 2019-06-11  Alexey Shvayka  <[email protected]>
 
+        JSC should throw if proxy set returns falsish in strict mode context
+        https://bugs.webkit.org/show_bug.cgi?id=177398
+
+        Reviewed by Yusuke Suzuki.
+
+        1. Add coverage for Proxy `set` trap returning falsy value in strict mode.
+        2. RegExp methods throw unless [[Set]] succeeds. Return `true` from Proxy `set` traps to fix the tests.
+
+        * stress/proxy-set.js: Add 2 test cases.
+        * stress/regexp-match-proxy.js: Fix test.
+        * stress/regexp-replace-proxy.js: Fix test.
+
+2019-06-11  Alexey Shvayka  <[email protected]>
+
         Error message for non-callable Proxy `construct` trap is misleading
         https://bugs.webkit.org/show_bug.cgi?id=198637
 

Modified: trunk/JSTests/stress/proxy-set.js (246345 => 246346)


--- trunk/JSTests/stress/proxy-set.js	2019-06-12 03:18:25 UTC (rev 246345)
+++ trunk/JSTests/stress/proxy-set.js	2019-06-12 03:18:53 UTC (rev 246346)
@@ -80,6 +80,56 @@
     }
 }
 
+(function() {
+    "use strict";
+    let target = {
+        x: 30
+    };
+
+    let handler = {
+        set: function() {
+            return false;
+        }
+    };
+
+    let proxy = new Proxy(target, handler);
+    for (let i = 0; i < 1000; i++) {
+        let threw = false;
+        try {
+            proxy.x = 40;
+        } catch(e) {
+            assert(e.toString() === "TypeError: Proxy object's 'set' trap returned falsy value for property 'x'");
+            threw = true;
+        }
+        assert(threw);
+    }
+})();
+
+(function() {
+    "use strict";
+    let target = {
+        x: 30
+    };
+
+    let handler = {
+        set: function() {
+            return false;
+        }
+    };
+
+    let proxy = new Proxy(target, handler);
+    for (let i = 0; i < 1000; i++) {
+        let threw = false;
+        try {
+            proxy[42] = 40;
+        } catch(e) {
+            assert(e.toString() === "TypeError: Proxy object's 'set' trap returned falsy value for property '42'");
+            threw = true;
+        }
+        assert(threw);
+    }
+})();
+
 {
     let target = { };
     Object.defineProperty(target, "x", {

Modified: trunk/JSTests/stress/regexp-match-proxy.js (246345 => 246346)


--- trunk/JSTests/stress/regexp-match-proxy.js	2019-06-12 03:18:25 UTC (rev 246345)
+++ trunk/JSTests/stress/regexp-match-proxy.js	2019-06-12 03:18:53 UTC (rev 246346)
@@ -53,6 +53,7 @@
             set.push(k);
             getSet.push(k);
             o[k] = v;
+            return true;
         }
     });
 
@@ -83,6 +84,7 @@
             set.push(k);
             getSet.push(k);
             o[k] = v;
+            return true;
         }
     });
 
@@ -117,6 +119,7 @@
             if (k.toString() == "lastIndex")
                 regExpGlobal_tx_Greedy.lastIndex = v;
             o[k] = v;
+            return true;
         }
     });
 
@@ -152,6 +155,7 @@
             if (k.toString() == "lastIndex")
                 regExpGlobalUnicode_digit_nonGreedy.lastIndex = v;
             o[k] = v;
+            return true;
         }
     });
 

Modified: trunk/JSTests/stress/regexp-replace-proxy.js (246345 => 246346)


--- trunk/JSTests/stress/regexp-replace-proxy.js	2019-06-12 03:18:25 UTC (rev 246345)
+++ trunk/JSTests/stress/regexp-replace-proxy.js	2019-06-12 03:18:53 UTC (rev 246346)
@@ -50,6 +50,7 @@
         {
             getSet.push(k);
             o[k] = v;
+            return true;
         }
     });
 
@@ -78,6 +79,7 @@
         {
             getSet.push(k);
             o[k] = v;
+            return true;
         }
     });
 
@@ -110,6 +112,7 @@
             if (k.toString() == "lastIndex")
                 regExp_phoneNumber.lastIndex = v;
             o[k] = v;
+            return true;
         }
     });
 
@@ -141,6 +144,7 @@
             if (k.toString() == "lastIndex")
                 regExpGlobalUnicode_digit_nonGreedy.lastIndex = v;
             o[k] = v;
+            return true;
         }
     });
 

Modified: trunk/Source/_javascript_Core/ChangeLog (246345 => 246346)


--- trunk/Source/_javascript_Core/ChangeLog	2019-06-12 03:18:25 UTC (rev 246345)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-06-12 03:18:53 UTC (rev 246346)
@@ -1,5 +1,21 @@
 2019-06-11  Alexey Shvayka  <[email protected]>
 
+        JSC should throw if proxy set returns falsish in strict mode context
+        https://bugs.webkit.org/show_bug.cgi?id=177398
+
+        Reviewed by Yusuke Suzuki.
+
+        Throw TypeError exception if Proxy's `set` trap returns falsy value.
+        (step 6.c of https://tc39.es/ecma262/#sec-putvalue)
+
+        * runtime/ProxyObject.cpp:
+        (JSC::ProxyObject::performPut):
+        (JSC::ProxyObject::put):
+        (JSC::ProxyObject::putByIndexCommon):
+        * runtime/ProxyObject.h:
+
+2019-06-11  Alexey Shvayka  <[email protected]>
+
         Error message for non-callable Proxy `construct` trap is misleading
         https://bugs.webkit.org/show_bug.cgi?id=198637
 

Modified: trunk/Source/_javascript_Core/runtime/ProxyObject.cpp (246345 => 246346)


--- trunk/Source/_javascript_Core/runtime/ProxyObject.cpp	2019-06-12 03:18:25 UTC (rev 246345)
+++ trunk/Source/_javascript_Core/runtime/ProxyObject.cpp	2019-06-12 03:18:53 UTC (rev 246346)
@@ -409,7 +409,7 @@
 }
 
 template <typename PerformDefaultPutFunction>
-bool ProxyObject::performPut(ExecState* exec, JSValue putValue, JSValue thisValue, PropertyName propertyName, PerformDefaultPutFunction performDefaultPut)
+bool ProxyObject::performPut(ExecState* exec, JSValue putValue, JSValue thisValue, PropertyName propertyName, PerformDefaultPutFunction performDefaultPut, bool shouldThrow)
 {
     NO_TAIL_CALLS();
 
@@ -448,8 +448,11 @@
     RETURN_IF_EXCEPTION(scope, false);
     bool trapResultAsBool = trapResult.toBoolean(exec);
     RETURN_IF_EXCEPTION(scope, false);
-    if (!trapResultAsBool)
+    if (!trapResultAsBool) {
+        if (shouldThrow)
+            throwVMTypeError(exec, scope, makeString("Proxy object's 'set' trap returned falsy value for property '", String(propertyName.uid()), "'"));
         return false;
+    }
 
     PropertyDescriptor descriptor;
     bool hasProperty = target->getOwnPropertyDescriptor(exec, propertyName, descriptor);
@@ -478,7 +481,7 @@
         JSObject* target = jsCast<JSObject*>(thisObject->target());
         return target->methodTable(vm)->put(target, exec, propertyName, value, slot);
     };
-    return thisObject->performPut(exec, value, slot.thisValue(), propertyName, performDefaultPut);
+    return thisObject->performPut(exec, value, slot.thisValue(), propertyName, performDefaultPut, slot.isStrictMode());
 }
 
 bool ProxyObject::putByIndexCommon(ExecState* exec, JSValue thisValue, unsigned propertyName, JSValue putValue, bool shouldThrow)
@@ -493,7 +496,7 @@
         PutPropertySlot slot(thisValue, isStrictMode); // We must preserve the "this" target of the putByIndex.
         return target->methodTable(vm)->put(target, exec, ident.impl(), putValue, slot);
     };
-    RELEASE_AND_RETURN(scope, performPut(exec, putValue, thisValue, ident.impl(), performDefaultPut));
+    RELEASE_AND_RETURN(scope, performPut(exec, putValue, thisValue, ident.impl(), performDefaultPut, shouldThrow));
 }
 
 bool ProxyObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)

Modified: trunk/Source/_javascript_Core/runtime/ProxyObject.h (246345 => 246346)


--- trunk/Source/_javascript_Core/runtime/ProxyObject.h	2019-06-12 03:18:25 UTC (rev 246345)
+++ trunk/Source/_javascript_Core/runtime/ProxyObject.h	2019-06-12 03:18:53 UTC (rev 246346)
@@ -100,7 +100,7 @@
     template <typename DefaultDeleteFunction>
     bool performDelete(ExecState*, PropertyName, DefaultDeleteFunction);
     template <typename PerformDefaultPutFunction>
-    bool performPut(ExecState*, JSValue putValue, JSValue thisValue, PropertyName, PerformDefaultPutFunction);
+    bool performPut(ExecState*, JSValue putValue, JSValue thisValue, PropertyName, PerformDefaultPutFunction, bool shouldThrow);
     bool performPreventExtensions(ExecState*);
     bool performIsExtensible(ExecState*);
     bool performDefineOwnProperty(ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to