Assertion failure for exception in "prototype" property getter and Reflect.construct
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Apr 2016 20:01:42 +0000 (20:01 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Apr 2016 20:01:42 +0000 (20:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157084

Reviewed by Mark Lam.

InternalFunction::createSubclassStrucuture may throw exceptions because it performs [[Get]] to
look up the "prototype" object. The current assertion is invalid.
We also found that Object constructor is not aware of new.target. This is filed[1].

[1]: https://bugs.webkit.org/show_bug.cgi?id=157196

* runtime/InternalFunction.cpp:
(JSC::InternalFunction::createSubclassStructure):
* tests/stress/create-subclass-structure-may-throw-exception-when-getting-prototype.js: Added.
(shouldThrow):
(bf):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200257 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/InternalFunction.cpp
Source/JavaScriptCore/tests/stress/create-subclass-structure-may-throw-exception-when-getting-prototype.js [new file with mode: 0644]

index 05a2bde..eec7935 100644 (file)
@@ -1,3 +1,22 @@
+2016-04-29  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Assertion failure for exception in "prototype" property getter and Reflect.construct
+        https://bugs.webkit.org/show_bug.cgi?id=157084
+
+        Reviewed by Mark Lam.
+
+        InternalFunction::createSubclassStrucuture may throw exceptions because it performs [[Get]] to
+        look up the "prototype" object. The current assertion is invalid.
+        We also found that Object constructor is not aware of new.target. This is filed[1].
+
+        [1]: https://bugs.webkit.org/show_bug.cgi?id=157196
+
+        * runtime/InternalFunction.cpp:
+        (JSC::InternalFunction::createSubclassStructure):
+        * tests/stress/create-subclass-structure-may-throw-exception-when-getting-prototype.js: Added.
+        (shouldThrow):
+        (bf):
+
 2016-04-29  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r200232.
index 200743c..a20a563 100644 (file)
@@ -110,7 +110,8 @@ Structure* InternalFunction::createSubclassStructure(ExecState* exec, JSValue ne
 
             // Note, Reflect.construct might cause the profile to churn but we don't care.
             JSObject* prototype = jsDynamicCast<JSObject*>(newTarget.get(exec, exec->propertyNames().prototype));
-            ASSERT(!exec->hadException());
+            if (exec->hadException())
+                return nullptr;
             if (prototype)
                 return targetFunction->rareData(vm)->createInternalFunctionAllocationStructureFromBase(vm, prototype, baseClass);
         } else {
diff --git a/Source/JavaScriptCore/tests/stress/create-subclass-structure-may-throw-exception-when-getting-prototype.js b/Source/JavaScriptCore/tests/stress/create-subclass-structure-may-throw-exception-when-getting-prototype.js
new file mode 100644 (file)
index 0000000..f78d1b3
--- /dev/null
@@ -0,0 +1,44 @@
+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)}`);
+}
+
+var bf = (function(){}).bind();
+Object.defineProperty(bf, "prototype", {
+    get() { throw Error("OK") }
+});
+
+[
+    Array,
+    Date,
+    Boolean,
+    Function,
+    Number,
+    String,
+    RegExp,
+    Error,
+    Uint8Array,
+    ArrayBuffer,
+    Promise,
+    Map,
+    WeakMap,
+    Set,
+    WeakSet,
+].forEach(function (constructor) {
+    shouldThrow(() => {
+        Reflect.construct(constructor, [], bf);
+    }, `Error: OK`);
+});
+
+// Proxy constructor is not aware of new.target.
+Reflect.construct(Proxy, [{}, {}], bf);