- Revision
- 272747
- Author
- [email protected]
- Date
- 2021-02-11 13:38:10 -0800 (Thu, 11 Feb 2021)
Log Message
SetIntegrityLevel should call [[DefineOwnProperty]] with partial descriptor
https://bugs.webkit.org/show_bug.cgi?id=221497
Reviewed by Yusuke Suzuki.
JSTests:
* stress/arguments-define-property-throws-out-of-memory.js: Added.
* stress/freeze-invokes-out-of-memory.js: Removed.
* stress/object-freeze-with-arguments-no-oom-error.js: Added.
* stress/object-freeze-with-proxy-defineProperty.js: Added.
Source/_javascript_Core:
This patch prevents [[GetOwnProperty]] result descriptor from being reused for
[[DefineOwnProperty]]. Instead, partial descriptor with only [[Configurable]]
and (conditionally) [[Writable]] fields is passed, which is observable by
ProxyObject's "defineProperty" trap (and possibly any other opaque object).
Also, replaces isDataDescriptor() check with negated isAccessorDescriptor()
as per spec [1], which is equivalent in this case yet is false dichotomy
for partial descriptors.
Aligns JSC with V8 and SpiderMonkey.
[1]: https://tc39.es/ecma262/#sec-setintegritylevel (step 7.b.ii)
* runtime/ObjectConstructor.cpp:
(JSC::setIntegrityLevel):
Modified Paths
Added Paths
Removed Paths
Diff
Modified: trunk/JSTests/ChangeLog (272746 => 272747)
--- trunk/JSTests/ChangeLog 2021-02-11 21:34:08 UTC (rev 272746)
+++ trunk/JSTests/ChangeLog 2021-02-11 21:38:10 UTC (rev 272747)
@@ -1,3 +1,15 @@
+2021-02-11 Alexey Shvayka <[email protected]>
+
+ SetIntegrityLevel should call [[DefineOwnProperty]] with partial descriptor
+ https://bugs.webkit.org/show_bug.cgi?id=221497
+
+ Reviewed by Yusuke Suzuki.
+
+ * stress/arguments-define-property-throws-out-of-memory.js: Added.
+ * stress/freeze-invokes-out-of-memory.js: Removed.
+ * stress/object-freeze-with-arguments-no-oom-error.js: Added.
+ * stress/object-freeze-with-proxy-defineProperty.js: Added.
+
2021-02-09 Yusuke Suzuki <[email protected]>
[JSC] C++ iteration should support fast iterator protocol
Added: trunk/JSTests/stress/arguments-define-property-throws-out-of-memory.js (0 => 272747)
--- trunk/JSTests/stress/arguments-define-property-throws-out-of-memory.js (rev 0)
+++ trunk/JSTests/stress/arguments-define-property-throws-out-of-memory.js 2021-02-11 21:38:10 UTC (rev 272747)
@@ -0,0 +1,24 @@
+function shouldThrow(func, errorMessage) {
+ var errorThrown = false;
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ errorThrown = true;
+ error = e;
+ }
+ if (!errorThrown)
+ throw new Error('not thrown');
+ if (String(error) !== errorMessage)
+ throw new Error(`bad error: ${String(error)}`);
+}
+
+function foo() {
+ Object.defineProperty(arguments, '0', {value: s});
+}
+
+let s = [0.1].toLocaleString().padEnd(2 ** 31 - 1, 'ab');
+
+shouldThrow(() => {
+ foo(s);
+}, `RangeError: Out of memory`);
Deleted: trunk/JSTests/stress/freeze-invokes-out-of-memory.js (272746 => 272747)
--- trunk/JSTests/stress/freeze-invokes-out-of-memory.js 2021-02-11 21:34:08 UTC (rev 272746)
+++ trunk/JSTests/stress/freeze-invokes-out-of-memory.js 2021-02-11 21:38:10 UTC (rev 272747)
@@ -1,24 +0,0 @@
-function shouldThrow(func, errorMessage) {
- var errorThrown = false;
- var error = null;
- try {
- func();
- } catch (e) {
- errorThrown = true;
- error = e;
- }
- if (!errorThrown)
- throw new Error('not thrown');
- if (String(error) !== errorMessage)
- throw new Error(`bad error: ${String(error)}`);
-}
-
-function foo() {
- Object.freeze(arguments);
-}
-
-let s = [0.1].toLocaleString().padEnd(2**31-1, 'ab');
-
-shouldThrow(() => {
- foo(s);
-}, `RangeError: Out of memory`);
Added: trunk/JSTests/stress/object-freeze-with-arguments-no-oom-error.js (0 => 272747)
--- trunk/JSTests/stress/object-freeze-with-arguments-no-oom-error.js (rev 0)
+++ trunk/JSTests/stress/object-freeze-with-arguments-no-oom-error.js 2021-02-11 21:38:10 UTC (rev 272747)
@@ -0,0 +1,6 @@
+function foo(a) {
+ Object.freeze(arguments);
+}
+
+let s = [0.1].toLocaleString().padEnd(2 ** 31 - 1, 'ab');
+foo(s);
Added: trunk/JSTests/stress/object-freeze-with-proxy-defineProperty.js (0 => 272747)
--- trunk/JSTests/stress/object-freeze-with-proxy-defineProperty.js (rev 0)
+++ trunk/JSTests/stress/object-freeze-with-proxy-defineProperty.js 2021-02-11 21:38:10 UTC (rev 272747)
@@ -0,0 +1,30 @@
+// See https://tc39.es/ecma262/#sec-setintegritylevel (step 7.b.ii)
+
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error(`Bad value: ${actual}!`);
+}
+
+var seenDescriptors = {};
+var proxy = new Proxy({
+ foo: 1,
+ get bar() {},
+ set bar(_v) {},
+}, {
+ defineProperty: function(target, key, descriptor) {
+ seenDescriptors[key] = descriptor;
+ return Reflect.defineProperty(target, key, descriptor);
+ },
+});
+
+Object.freeze(proxy);
+
+shouldBe(seenDescriptors.foo.value, undefined);
+shouldBe(seenDescriptors.foo.writable, false);
+shouldBe(seenDescriptors.foo.enumerable, undefined);
+shouldBe(seenDescriptors.foo.configurable, false);
+
+shouldBe(seenDescriptors.bar.get, undefined);
+shouldBe(seenDescriptors.bar.set, undefined);
+shouldBe(seenDescriptors.bar.enumerable, undefined);
+shouldBe(seenDescriptors.bar.configurable, false);
Modified: trunk/Source/_javascript_Core/ChangeLog (272746 => 272747)
--- trunk/Source/_javascript_Core/ChangeLog 2021-02-11 21:34:08 UTC (rev 272746)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-02-11 21:38:10 UTC (rev 272747)
@@ -1,3 +1,26 @@
+2021-02-11 Alexey Shvayka <[email protected]>
+
+ SetIntegrityLevel should call [[DefineOwnProperty]] with partial descriptor
+ https://bugs.webkit.org/show_bug.cgi?id=221497
+
+ Reviewed by Yusuke Suzuki.
+
+ This patch prevents [[GetOwnProperty]] result descriptor from being reused for
+ [[DefineOwnProperty]]. Instead, partial descriptor with only [[Configurable]]
+ and (conditionally) [[Writable]] fields is passed, which is observable by
+ ProxyObject's "defineProperty" trap (and possibly any other opaque object).
+
+ Also, replaces isDataDescriptor() check with negated isAccessorDescriptor()
+ as per spec [1], which is equivalent in this case yet is false dichotomy
+ for partial descriptors.
+
+ Aligns JSC with V8 and SpiderMonkey.
+
+ [1]: https://tc39.es/ecma262/#sec-setintegritylevel (step 7.b.ii)
+
+ * runtime/ObjectConstructor.cpp:
+ (JSC::setIntegrityLevel):
+
2021-02-11 Don Olmstead <[email protected]>
[CMake] WEBKIT_EXECUTABLE can incorrectly link framework
Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp (272746 => 272747)
--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2021-02-11 21:34:08 UTC (rev 272746)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2021-02-11 21:38:10 UTC (rev 272747)
@@ -715,12 +715,13 @@
if (level == IntegrityLevel::Sealed)
desc.setConfigurable(false);
else {
- bool hasPropertyDescriptor = object->getOwnPropertyDescriptor(globalObject, propertyName, desc);
+ PropertyDescriptor currentDesc;
+ bool hasPropertyDescriptor = object->getOwnPropertyDescriptor(globalObject, propertyName, currentDesc);
RETURN_IF_EXCEPTION(scope, false);
if (!hasPropertyDescriptor)
continue;
- if (desc.isDataDescriptor())
+ if (!currentDesc.isAccessorDescriptor())
desc.setWritable(false);
desc.setConfigurable(false);