Title: [272747] trunk
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);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to