Title: [245675] trunk
Revision
245675
Author
tzaga...@apple.com
Date
2019-05-23 00:06:20 -0700 (Thu, 23 May 2019)

Log Message

createListFromArrayLike should throw if value is not an object
https://bugs.webkit.org/show_bug.cgi?id=198138

Reviewed by Yusuke Suzuki.

JSTests:

* stress/create-list-from-array-like-not-object.js: Added.
(testValid):
(testInvalid):
* stress/proxy-get-own-property-names-should-not-clear-previous-results.js:
(opt):
* stress/proxy-proto-enumerator.js: Added.
(main):
* stress/proxy-proto-own-keys.js: Added.
(assert):
(ownKeys):

Source/_javascript_Core:

According to the spec[1], createListFromArrayLike should throw a type error if the array-like value
passed in is not an object.
[1]: https://www.ecma-international.org/ecma-262/9.0/index.html#sec-createlistfromarraylike

* runtime/JSObjectInlines.h:
(JSC::createListFromArrayLike):
* runtime/ProxyObject.cpp:
(JSC::ProxyObject::performGetOwnPropertyNames):
* runtime/ReflectObject.cpp:
(JSC::reflectObjectConstruct):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (245674 => 245675)


--- trunk/JSTests/ChangeLog	2019-05-23 06:57:34 UTC (rev 245674)
+++ trunk/JSTests/ChangeLog	2019-05-23 07:06:20 UTC (rev 245675)
@@ -1,3 +1,21 @@
+2019-05-23  Tadeu Zagallo  <tzaga...@apple.com>
+
+        createListFromArrayLike should throw if value is not an object
+        https://bugs.webkit.org/show_bug.cgi?id=198138
+
+        Reviewed by Yusuke Suzuki.
+
+        * stress/create-list-from-array-like-not-object.js: Added.
+        (testValid):
+        (testInvalid):
+        * stress/proxy-get-own-property-names-should-not-clear-previous-results.js:
+        (opt):
+        * stress/proxy-proto-enumerator.js: Added.
+        (main):
+        * stress/proxy-proto-own-keys.js: Added.
+        (assert):
+        (ownKeys):
+
 2019-05-22  Yusuke Suzuki  <ysuz...@apple.com>
 
         [JSC] ArrayAllocationProfile should not access to butterfly in concurrent compiler

Added: trunk/JSTests/stress/create-list-from-array-like-not-object.js (0 => 245675)


--- trunk/JSTests/stress/create-list-from-array-like-not-object.js	                        (rev 0)
+++ trunk/JSTests/stress/create-list-from-array-like-not-object.js	2019-05-23 07:06:20 UTC (rev 245675)
@@ -0,0 +1,25 @@
+function testValid(value) {
+    const foo = {x: 0};
+    foo.__proto__ = new Proxy({}, { ownKeys() { return value; } });
+    for (const x in foo) { }
+}
+
+testValid({});
+testValid([]);
+testValid(["x", Symbol("y")]);
+testValid({ length: 1, 0: 'x' });
+
+function testInvalid(value) {
+    try {
+        testValid(value);
+        throw new Error('should have thrown');
+    } catch (err) {
+        if (err.message !== "Proxy handler's 'ownKeys' method must return an object")
+            throw new Error("Expected createListFromArrayLike error");
+    }
+}
+
+testInvalid(true);
+testInvalid(false);
+testInvalid(null);
+testInvalid(0);

Modified: trunk/JSTests/stress/proxy-get-own-property-names-should-not-clear-previous-results.js (245674 => 245675)


--- trunk/JSTests/stress/proxy-get-own-property-names-should-not-clear-previous-results.js	2019-05-23 06:57:34 UTC (rev 245674)
+++ trunk/JSTests/stress/proxy-get-own-property-names-should-not-clear-previous-results.js	2019-05-23 07:06:20 UTC (rev 245675)
@@ -6,7 +6,7 @@
 a = {defineProperties:Object};
 function opt() {
     a.__proto__ = new Proxy(Object,{ownKeys:opt});
-    return 1;
+    return [];
 }
 for(var i=0;i<400;i=i+1) {
     var prop = null;

Added: trunk/JSTests/stress/proxy-proto-enumerator.js (0 => 245675)


--- trunk/JSTests/stress/proxy-proto-enumerator.js	                        (rev 0)
+++ trunk/JSTests/stress/proxy-proto-enumerator.js	2019-05-23 07:06:20 UTC (rev 245675)
@@ -0,0 +1,10 @@
+//@ requireOptions("--forceEagerCompilation=true", "--useConcurrentJIT=false")
+
+function main() {
+    const foo = {x: 0};
+    foo.__proto__ = new Proxy({}, { ownKeys() { return []; } });
+    for (const x in foo) { }
+}
+
+for (let i = 0; i < 0x1000; i++)
+    main();

Added: trunk/JSTests/stress/proxy-proto-own-keys.js (0 => 245675)


--- trunk/JSTests/stress/proxy-proto-own-keys.js	                        (rev 0)
+++ trunk/JSTests/stress/proxy-proto-own-keys.js	2019-05-23 07:06:20 UTC (rev 245675)
@@ -0,0 +1,15 @@
+function assert(condition, message) {
+    if (!condition)
+        throw new Error(message);
+}
+
+const foo = {x: 0};
+foo.__proto__ = new Proxy({y: 1}, { ownKeys() { return ['y']; } });
+const keys = [];
+for (const x in foo) {
+    keys.push(x);
+}
+
+assert(keys.length == 2, "Should have 2 keys");
+assert(keys.includes("x"), "Should have key `x`");
+assert(keys.includes("y"), "Should have key `y`");

Modified: trunk/Source/_javascript_Core/ChangeLog (245674 => 245675)


--- trunk/Source/_javascript_Core/ChangeLog	2019-05-23 06:57:34 UTC (rev 245674)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-05-23 07:06:20 UTC (rev 245675)
@@ -1,3 +1,21 @@
+2019-05-23  Tadeu Zagallo  <tzaga...@apple.com>
+
+        createListFromArrayLike should throw if value is not an object
+        https://bugs.webkit.org/show_bug.cgi?id=198138
+
+        Reviewed by Yusuke Suzuki.
+
+        According to the spec[1], createListFromArrayLike should throw a type error if the array-like value
+        passed in is not an object.
+        [1]: https://www.ecma-international.org/ecma-262/9.0/index.html#sec-createlistfromarraylike
+
+        * runtime/JSObjectInlines.h:
+        (JSC::createListFromArrayLike):
+        * runtime/ProxyObject.cpp:
+        (JSC::ProxyObject::performGetOwnPropertyNames):
+        * runtime/ReflectObject.cpp:
+        (JSC::reflectObjectConstruct):
+
 2019-05-22  Yusuke Suzuki  <ysuz...@apple.com>
 
         [JSC] UnlinkedMetadataTable's offset table should be small

Modified: trunk/Source/_javascript_Core/runtime/JSObjectInlines.h (245674 => 245675)


--- trunk/Source/_javascript_Core/runtime/JSObjectInlines.h	2019-05-23 06:57:34 UTC (rev 245674)
+++ trunk/Source/_javascript_Core/runtime/JSObjectInlines.h	2019-05-23 07:06:20 UTC (rev 245675)
@@ -33,10 +33,15 @@
 
 // Section 7.3.17 of the spec.
 template <typename AddFunction> // Add function should have a type like: (JSValue, RuntimeType) -> bool
-void createListFromArrayLike(ExecState* exec, JSValue arrayLikeValue, RuntimeTypeMask legalTypesFilter, const String& errorMessage, AddFunction addFunction)
+void createListFromArrayLike(ExecState* exec, JSValue arrayLikeValue, RuntimeTypeMask legalTypesFilter, const String& notAnObjectErroMessage, const String& illegalTypeErrorMessage, AddFunction addFunction)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (!arrayLikeValue.isObject()) {
+        throwTypeError(exec, scope, notAnObjectErroMessage);
+        return;
+    }
     
     Vector<JSValue> result;
     JSValue lengthProperty = arrayLikeValue.get(exec, vm.propertyNames->length);
@@ -51,7 +56,7 @@
         
         RuntimeType type = runtimeTypeForValue(vm, next);
         if (!(type & legalTypesFilter)) {
-            throwTypeError(exec, scope, errorMessage);
+            throwTypeError(exec, scope, illegalTypeErrorMessage);
             return;
         }
         

Modified: trunk/Source/_javascript_Core/runtime/ProxyObject.cpp (245674 => 245675)


--- trunk/Source/_javascript_Core/runtime/ProxyObject.cpp	2019-05-23 06:57:34 UTC (rev 245674)
+++ trunk/Source/_javascript_Core/runtime/ProxyObject.cpp	2019-05-23 07:06:20 UTC (rev 245675)
@@ -974,7 +974,7 @@
         };
 
         RuntimeTypeMask dontThrowAnExceptionTypeFilter = TypeString | TypeSymbol;
-        createListFromArrayLike(exec, arrayLikeObject, dontThrowAnExceptionTypeFilter, "Proxy handler's 'ownKeys' method must return an array-like object containing only Strings and Symbols"_s, addPropName);
+        createListFromArrayLike(exec, arrayLikeObject, dontThrowAnExceptionTypeFilter, "Proxy handler's 'ownKeys' method must return an object"_s, "Proxy handler's 'ownKeys' method must return an array-like object containing only Strings and Symbols"_s, addPropName);
         RETURN_IF_EXCEPTION(scope, void());
     }
 

Modified: trunk/Source/_javascript_Core/runtime/ReflectObject.cpp (245674 => 245675)


--- trunk/Source/_javascript_Core/runtime/ReflectObject.cpp	2019-05-23 06:57:34 UTC (rev 245674)
+++ trunk/Source/_javascript_Core/runtime/ReflectObject.cpp	2019-05-23 07:06:20 UTC (rev 245675)
@@ -113,7 +113,7 @@
     if (!argumentsObject)
         return JSValue::encode(throwTypeError(exec, scope, "Reflect.construct requires the second argument be an object"_s));
 
-    createListFromArrayLike(exec, argumentsObject, RuntimeTypeMaskAllTypes, "This error must not be raised"_s, [&] (JSValue value, RuntimeType) -> bool {
+    createListFromArrayLike(exec, argumentsObject, RuntimeTypeMaskAllTypes, "This error must not be raised"_s, "This error must not be raised"_s, [&] (JSValue value, RuntimeType) -> bool {
         arguments.append(value);
         return false;
     });
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to