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);