Make custom Error properties (line, column, sourceURL) configurable and writable
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Aug 2016 22:49:26 +0000 (22:49 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Aug 2016 22:49:26 +0000 (22:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160984
<rdar://problem/27905979>

Patch by Joseph Pecoraro <pecoraro@apple.com> on 2016-08-19
Reviewed by Saam Barati.

JSTests:

* stress/native-error-properties.js: Added.
(assert):
(shouldNotThrow):

(checkEmptyErrorPropertiesDescriptors):
(checkNonEmptyErrorPropertiesDescriptors):
The spec only describes the "message" property, so
ensure it has the right descriptor attributes.

(checkErrorPropertiesWritable):
Ensure common error property names are writable.
In strict mode this would have thrown an exception
if they were readonly.

Source/JavaScriptCore:

* runtime/Error.cpp:
(JSC::addErrorInfoAndGetBytecodeOffset):
(JSC::addErrorInfo):

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

JSTests/ChangeLog
JSTests/stress/native-error-properties.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/Error.cpp

index 3ef2db4..7ed0d48 100644 (file)
@@ -1,3 +1,25 @@
+2016-08-19  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Make custom Error properties (line, column, sourceURL) configurable and writable
+        https://bugs.webkit.org/show_bug.cgi?id=160984
+        <rdar://problem/27905979>
+
+        Reviewed by Saam Barati.
+
+        * stress/native-error-properties.js: Added.
+        (assert):
+        (shouldNotThrow):
+
+        (checkEmptyErrorPropertiesDescriptors):
+        (checkNonEmptyErrorPropertiesDescriptors):
+        The spec only describes the "message" property, so
+        ensure it has the right descriptor attributes.
+
+        (checkErrorPropertiesWritable):
+        Ensure common error property names are writable.
+        In strict mode this would have thrown an exception
+        if they were readonly.
+
 2016-08-18  Mark Lam  <mark.lam@apple.com>
 
         ScopedArguments is using the wrong owner object for a write barrier.
diff --git a/JSTests/stress/native-error-properties.js b/JSTests/stress/native-error-properties.js
new file mode 100644 (file)
index 0000000..ecc56b1
--- /dev/null
@@ -0,0 +1,79 @@
+"use strict";
+
+function assert(b) {
+    if (!b)
+        throw new Error("Bad assertion");
+}
+
+function shouldNotThrow(expr) {
+    let testFunc = new Function(expr);
+    let error;
+    try {
+        testFunc();
+    } catch (e) {
+        error = e;
+    }
+    assert(!error);
+}
+
+function checkEmptyErrorPropertiesDescriptors(error) {
+    let descriptor = Object.getOwnPropertyDescriptor(error, "message");
+    assert(descriptor === undefined);
+}
+
+function checkNonEmptyErrorPropertiesDescriptors(error) {
+    let descriptor = Object.getOwnPropertyDescriptor(error, "message");
+    assert(descriptor.configurable);
+    assert(!descriptor.enumerable);
+    assert(descriptor.writable);
+}
+
+function checkErrorPropertiesWritable(error) {
+    let properties = ["name", "message", "line", "lineNumber", "column", "columnNumber", "sourceURL", "stack"];
+    for (let p of properties) {
+        assert(error[p] !== 999);
+        error[p] = 999;
+        assert(error[p] === 999);
+    }
+}
+
+// User created error instances.
+let errorConstructors = [Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError];
+for (let constructor of errorConstructors) {
+    shouldNotThrow(`checkErrorPropertiesWritable(new ${constructor.name})`);
+    shouldNotThrow(`checkEmptyErrorPropertiesDescriptors(new ${constructor.name})`);
+    shouldNotThrow(`checkNonEmptyErrorPropertiesDescriptors(new ${constructor.name}('message'))`);
+}
+
+// Engine created error instances.
+var globalError = null;
+
+try {
+    eval("{");
+} catch (e) {
+    globalError = e;
+    assert(e.name === "SyntaxError");
+    assert(e.message.length);
+    shouldNotThrow("checkNonEmptyErrorPropertiesDescriptors(globalError)");
+    shouldNotThrow("checkErrorPropertiesWritable(globalError)");
+}
+
+try {
+    a.b.c;
+} catch (e) {
+    globalError = e;
+    assert(e.name === "ReferenceError");
+    assert(e.message.length);
+    shouldNotThrow("checkNonEmptyErrorPropertiesDescriptors(globalError)");
+    shouldNotThrow("checkErrorPropertiesWritable(globalError)");
+}
+
+try {
+    undefined.x;
+} catch (e) {
+    globalError = e;
+    assert(e.name === "TypeError");
+    assert(e.message.length);
+    shouldNotThrow("checkNonEmptyErrorPropertiesDescriptors(globalError)");
+    shouldNotThrow("checkErrorPropertiesWritable(globalError)");
+}
index d9e2545..64bcf10 100644 (file)
@@ -1,5 +1,17 @@
 2016-08-19  Joseph Pecoraro  <pecoraro@apple.com>
 
+        Make custom Error properties (line, column, sourceURL) configurable and writable
+        https://bugs.webkit.org/show_bug.cgi?id=160984
+        <rdar://problem/27905979>
+
+        Reviewed by Saam Barati.
+
+        * runtime/Error.cpp:
+        (JSC::addErrorInfoAndGetBytecodeOffset):
+        (JSC::addErrorInfo):
+
+2016-08-19  Joseph Pecoraro  <pecoraro@apple.com>
+
         Remove empty files and empty namespace blocks
         https://bugs.webkit.org/show_bug.cgi?id=160990
 
index ebfd6ea..21152b5 100644 (file)
@@ -159,12 +159,12 @@ bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM& vm, JSObject* obj, bo
         unsigned line;
         unsigned column;
         firstNonNativeFrame->computeLineAndColumn(line, column);
-        obj->putDirect(vm, vm.propertyNames->line, jsNumber(line), ReadOnly | DontDelete);
-        obj->putDirect(vm, vm.propertyNames->column, jsNumber(column), ReadOnly | DontDelete);
+        obj->putDirect(vm, vm.propertyNames->line, jsNumber(line));
+        obj->putDirect(vm, vm.propertyNames->column, jsNumber(column));
 
         String frameSourceURL = firstNonNativeFrame->sourceURL();
         if (!frameSourceURL.isEmpty())
-            obj->putDirect(vm, vm.propertyNames->sourceURL, jsString(&vm, frameSourceURL), ReadOnly | DontDelete);
+            obj->putDirect(vm, vm.propertyNames->sourceURL, jsString(&vm, frameSourceURL));
 
         obj->putDirect(vm, vm.propertyNames->stack, Interpreter::stackTraceAsString(vm, stackTrace), DontEnum);
 
@@ -185,9 +185,9 @@ JSObject* addErrorInfo(CallFrame* callFrame, JSObject* error, int line, const So
     const String& sourceURL = source.provider()->url();
 
     if (line != -1)
-        error->putDirect(*vm, Identifier::fromString(vm, linePropertyName), jsNumber(line), ReadOnly | DontDelete);
+        error->putDirect(*vm, Identifier::fromString(vm, linePropertyName), jsNumber(line));
     if (!sourceURL.isNull())
-        error->putDirect(*vm, Identifier::fromString(vm, sourceURLPropertyName), jsString(vm, sourceURL), ReadOnly | DontDelete);
+        error->putDirect(*vm, Identifier::fromString(vm, sourceURLPropertyName), jsString(vm, sourceURL));
     return error;
 }