Title: [218845] trunk
Revision
218845
Author
sbar...@apple.com
Date
2017-06-27 14:37:46 -0700 (Tue, 27 Jun 2017)

Log Message

Function constructor needs to follow the spec and validate parameters and body independently
https://bugs.webkit.org/show_bug.cgi?id=173303
<rdar://problem/32732526>

Reviewed by Keith Miller.

JSTests:

* ChakraCore/test/Function/FuncBodyES5.baseline-jsc:
* stress/function-constructor-semantics.js: Added.
(assert):
(hasSyntaxError):
(foo):
(async.foo):
(testError):
(testOK.toString):
(toString):

LayoutTests/imported/w3c:

* web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt:
* web-platform-tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late-expected.txt:
* web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-attribute-expected.txt:
* web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-body-onerror-expected.txt:

Source/_javascript_Core:

The Function constructor must check the arguments and body strings
independently for syntax errors. People rely on this specified behavior
to verify that a particular string is a valid function body. We used
to check these things strings concatenated together, instead of
independently. For example, this used to be valid: `Function("/*", "*/){")`.
However, we should throw a syntax error here since "(/*)" is not a valid
parameter list, and "*/){" is not a valid body.

To implement the specified behavior, we check the syntax independently of
both the body and the parameter list. To check that the parameter list has
valid syntax, we check that it is valid if in a function with an empty body.
To check that the body has valid syntax, we check it is valid in a function
with an empty parameter list.

* runtime/FunctionConstructor.cpp:
(JSC::constructFunctionSkippingEvalEnabledCheck):

LayoutTests:

* fast/dom/attribute-event-listener-errors-expected.txt:
* fast/events/attribute-listener-deletion-crash-expected.txt:
* fast/events/window-onerror-syntax-error-in-attr-expected.txt:
* js/dom/invalid-syntax-for-function-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChakraCore/test/Function/FuncBodyES5.baseline-jsc (218844 => 218845)


--- trunk/JSTests/ChakraCore/test/Function/FuncBodyES5.baseline-jsc	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/JSTests/ChakraCore/test/Function/FuncBodyES5.baseline-jsc	2017-06-27 21:37:46 UTC (rev 218845)
@@ -9,13 +9,13 @@
 PASS: 8: new Function succeeded as expected
 PASS: 9: new Function succeeded as expected
 PASS: 10: new Function succeeded as expected
-PASS: 100: new Function failed as expected. SyntaxError: Parser error
-PASS: 100: new Function failed as expected. SyntaxError: Parser error
-PASS: 101: new Function failed as expected. SyntaxError: Parser error
-PASS: 102: new Function failed as expected. SyntaxError: Parser error
-PASS: 103: new Function failed as expected. SyntaxError: Parser error
-PASS: 104: new Function failed as expected. SyntaxError: Invalid character: '\0'
-PASS: 105: new Function failed as expected. SyntaxError: Parser error
+PASS: 100: new Function failed as expected. SyntaxError: Unexpected token '{'. Expected ')' to end a compound _expression_.
+PASS: 100: new Function failed as expected. SyntaxError: Unexpected token '{'. Expected ')' to end a compound _expression_.
+PASS: 101: new Function failed as expected. SyntaxError: Unexpected keyword 'function'. Expected ')' to end a compound _expression_.
+PASS: 102: new Function failed as expected. SyntaxError: Unexpected keyword 'function'. Expected ')' to end a compound _expression_.
+PASS: 103: new Function failed as expected. SyntaxError: Unexpected keyword 'function'. Expected ')' to end a compound _expression_.
+PASS: 104: new Function failed as expected. SyntaxError: Unexpected token ';'. Expected ')' to end a compound _expression_.
+PASS: 105: new Function failed as expected. SyntaxError: Unexpected token ';'. Expected ')' to end a compound _expression_.
 PASS: 200: new Function failed as expected. SyntaxError: Unexpected token ','. Expected a parameter pattern or a ')' in parameter list.
 PASS: 200: new Function failed as expected. SyntaxError: Unexpected token ','. Expected a parameter pattern or a ')' in parameter list.
 PASS: 201: new Function failed as expected. SyntaxError: Unexpected token ','. Expected a parameter pattern or a ')' in parameter list.

Modified: trunk/JSTests/ChangeLog (218844 => 218845)


--- trunk/JSTests/ChangeLog	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/JSTests/ChangeLog	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,3 +1,21 @@
+2017-06-27  Saam Barati  <sbar...@apple.com>
+
+        Function constructor needs to follow the spec and validate parameters and body independently
+        https://bugs.webkit.org/show_bug.cgi?id=173303
+        <rdar://problem/32732526>
+
+        Reviewed by Keith Miller.
+
+        * ChakraCore/test/Function/FuncBodyES5.baseline-jsc:
+        * stress/function-constructor-semantics.js: Added.
+        (assert):
+        (hasSyntaxError):
+        (foo):
+        (async.foo):
+        (testError):
+        (testOK.toString):
+        (toString):
+
 2017-06-26  Saam Barati  <sbar...@apple.com>
 
         RegExpPrototype.js builtin uses for-of iteration which is almost certainly incorrect

Added: trunk/JSTests/stress/function-constructor-semantics.js (0 => 218845)


--- trunk/JSTests/stress/function-constructor-semantics.js	                        (rev 0)
+++ trunk/JSTests/stress/function-constructor-semantics.js	2017-06-27 21:37:46 UTC (rev 218845)
@@ -0,0 +1,64 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad");
+}
+
+function hasSyntaxError(f) {
+    let threw = false;
+    try {
+        f();
+    } catch(e) {
+        threw = e instanceof SyntaxError;
+    }
+    return threw;
+}
+
+let functions = [
+    Function,
+    (function*foo(){}).__proto__.constructor,
+    (async function foo(){}).__proto__.constructor,
+];
+
+function testError(...args) {
+    for (let f of functions) {
+        assert(hasSyntaxError(() => (f(...args))));
+    }
+}
+
+function testOK(...args) {
+    for (let f of functions) {
+        assert(!hasSyntaxError(() => (f(...args))));
+    }
+}
+
+testError("a", "b", "/*", "");
+testError("/*", "*/){");
+testError("a=super()", "body;");
+testError("a=super.foo", "body;");
+testError("super();");
+testError("super.foo;");
+testError("a", "b", "/*", "");
+testError("a", "'use strict'; let a;");
+testError("/*", "*/");
+testError("/*", "*/");
+testError("a=20", "'use strict';");
+testError("{a}", "'use strict';");
+testError("...args", "'use strict';");
+testError("...args", "b", "");
+testError("//", "b", "");
+
+testOK("/*", "*/", "");
+testOK("a", "/*b", "*/", "'use strict'; let b");
+testOK("{a}", "return a;");
+testOK("a", "...args", "");
+testOK("");
+testOK("let a");
+testOK(undefined);
+testOK("//");
+
+let str = "";
+testOK({toString() { str += "1"; return "a"}}, {toString() { str += "2"; return "b"}}, {toString() { str += "3"; return "body;"}});
+let target = "";
+for (let i = 0; i < functions.length; ++i)
+    target += "123";
+assert(str === target);

Modified: trunk/LayoutTests/ChangeLog (218844 => 218845)


--- trunk/LayoutTests/ChangeLog	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/ChangeLog	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,3 +1,16 @@
+2017-06-27  Saam Barati  <sbar...@apple.com>
+
+        Function constructor needs to follow the spec and validate parameters and body independently
+        https://bugs.webkit.org/show_bug.cgi?id=173303
+        <rdar://problem/32732526>
+
+        Reviewed by Keith Miller.
+
+        * fast/dom/attribute-event-listener-errors-expected.txt:
+        * fast/events/attribute-listener-deletion-crash-expected.txt:
+        * fast/events/window-onerror-syntax-error-in-attr-expected.txt:
+        * js/dom/invalid-syntax-for-function-expected.txt:
+
 2017-06-27  John Wilander  <wilan...@apple.com>
 
         Resource Load Statistics: Add telemetry

Modified: trunk/LayoutTests/fast/dom/attribute-event-listener-errors-expected.txt (218844 => 218845)


--- trunk/LayoutTests/fast/dom/attribute-event-listener-errors-expected.txt	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/fast/dom/attribute-event-listener-errors-expected.txt	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,4 +1,4 @@
 CONSOLE MESSAGE: line 4: ReferenceError: Can't find variable: error
-CONSOLE MESSAGE: line 5: SyntaxError: Invalid character: '@'
+CONSOLE MESSAGE: line 9: SyntaxError: Invalid character: '@'
 This test verifies that an attribute event listener error shows the right line number even if the attribute contains newlines.
   

Modified: trunk/LayoutTests/fast/events/attribute-listener-deletion-crash-expected.txt (218844 => 218845)


--- trunk/LayoutTests/fast/events/attribute-listener-deletion-crash-expected.txt	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/fast/events/attribute-listener-deletion-crash-expected.txt	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,21 +1,21 @@
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
-CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
+CONSOLE MESSAGE: line 2: SyntaxError: Unexpected token '|'
 PASS

Modified: trunk/LayoutTests/fast/events/window-onerror-syntax-error-in-attr-expected.txt (218844 => 218845)


--- trunk/LayoutTests/fast/events/window-onerror-syntax-error-in-attr-expected.txt	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/fast/events/window-onerror-syntax-error-in-attr-expected.txt	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,6 +1,6 @@
 Test that window.onerror is called on window object when there is a syntax error in attribute handler. Bug 70991.
 
-Main frame window.onerror: SyntaxError: Unexpected token '%' at window-onerror-syntax-error-in-attr.html:10:38 SyntaxError: Unexpected token '%'
-Main frame window.onerror: SyntaxError: Unexpected token '%' at window-onerror-syntax-error-in-attr.html:36:38 SyntaxError: Unexpected token '%'
-Main frame window.onerror: SyntaxError: Unexpected token '%' at window-onerror-syntax-error-in-attr.html:36:14 SyntaxError: Unexpected token '%'
+Main frame window.onerror: SyntaxError: Unexpected token '%' at window-onerror-syntax-error-in-attr.html:11:38 SyntaxError: Unexpected token '%'
+Main frame window.onerror: SyntaxError: Unexpected token '%' at window-onerror-syntax-error-in-attr.html:37:38 SyntaxError: Unexpected token '%'
+Main frame window.onerror: SyntaxError: Unexpected token '%' at window-onerror-syntax-error-in-attr.html:37:14 SyntaxError: Unexpected token '%'
 Button 1 Button 2 Button 3

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (218844 => 218845)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,3 +1,16 @@
+2017-06-27  Saam Barati  <sbar...@apple.com>
+
+        Function constructor needs to follow the spec and validate parameters and body independently
+        https://bugs.webkit.org/show_bug.cgi?id=173303
+        <rdar://problem/32732526>
+
+        Reviewed by Keith Miller.
+
+        * web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt:
+        * web-platform-tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late-expected.txt:
+        * web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-attribute-expected.txt:
+        * web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-body-onerror-expected.txt:
+
 2017-06-27  Frederic Wang  <fw...@igalia.com>
 
         Some tests to verify forbidden frame navigation time out

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt (218844 => 218845)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/inline-event-handler-ordering-expected.txt	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,5 +1,5 @@
 CONSOLE MESSAGE: line 19: SyntaxError: Unexpected token '}'
-CONSOLE MESSAGE: line 52: SyntaxError: Unexpected token '}'
+CONSOLE MESSAGE: line 54: SyntaxError: Unexpected token '}'
 
 PASS Inline event handlers retain their ordering when invalid and force-compiled 
 PASS Inline event handlers retain their ordering when invalid and force-compiled via dispatch 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late-expected.txt (218844 => 218845)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late-expected.txt	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late-expected.txt	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,5 +1,5 @@
-CONSOLE MESSAGE: line 24: SyntaxError: Parser error
-CONSOLE MESSAGE: line 21: SyntaxError: Parser error
+CONSOLE MESSAGE: line 26: SyntaxError: Unexpected token '}'. Expected ')' to end a compound _expression_.
+CONSOLE MESSAGE: line 21: SyntaxError: Unexpected token '}'. Expected ')' to end a compound _expression_.
 
 FAIL Invalid uncompiled raw handlers should only be compiled when about to call them. assert_array_equals: lengths differ, expected 3 got 4
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-attribute-expected.txt (218844 => 218845)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-attribute-expected.txt	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-attribute-expected.txt	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 24: SyntaxError: Unexpected end of script
+CONSOLE MESSAGE: line 26: SyntaxError: Unexpected token ')'
 
 PASS window.onerror - compile error in attribute 
 PASS window.onerror - compile error in attribute (column) 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-body-onerror-expected.txt (218844 => 218845)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-body-onerror-expected.txt	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/compile-error-in-body-onerror-expected.txt	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,5 +1,5 @@
 CONSOLE MESSAGE: line 19: SyntaxError: Unexpected token ')'
-CONSOLE MESSAGE: line 16: SyntaxError: Unexpected end of script
+CONSOLE MESSAGE: line 18: SyntaxError: Unexpected token ')'
 
 PASS window.onerror - compile error in <body onerror> 
 

Modified: trunk/LayoutTests/js/dom/invalid-syntax-for-function-expected.txt (218844 => 218845)


--- trunk/LayoutTests/js/dom/invalid-syntax-for-function-expected.txt	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/LayoutTests/js/dom/invalid-syntax-for-function-expected.txt	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,3 +1,3 @@
-CONSOLE MESSAGE: line 1: SyntaxError: Invalid character: '#'
+CONSOLE MESSAGE: line 2: SyntaxError: Invalid character: '#'
 This test ensures we don't crash when we are given garbage for an attribute expecting a function.
 https://bugs.webkit.org/show_bug.cgi?id=19025

Modified: trunk/Source/_javascript_Core/ChangeLog (218844 => 218845)


--- trunk/Source/_javascript_Core/ChangeLog	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-06-27 21:37:46 UTC (rev 218845)
@@ -1,3 +1,28 @@
+2017-06-27  Saam Barati  <sbar...@apple.com>
+
+        Function constructor needs to follow the spec and validate parameters and body independently
+        https://bugs.webkit.org/show_bug.cgi?id=173303
+        <rdar://problem/32732526>
+
+        Reviewed by Keith Miller.
+
+        The Function constructor must check the arguments and body strings
+        independently for syntax errors. People rely on this specified behavior
+        to verify that a particular string is a valid function body. We used
+        to check these things strings concatenated together, instead of
+        independently. For example, this used to be valid: `Function("/*", "*/){")`.
+        However, we should throw a syntax error here since "(/*)" is not a valid
+        parameter list, and "*/){" is not a valid body.
+        
+        To implement the specified behavior, we check the syntax independently of
+        both the body and the parameter list. To check that the parameter list has
+        valid syntax, we check that it is valid if in a function with an empty body.
+        To check that the body has valid syntax, we check it is valid in a function
+        with an empty parameter list.
+
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunctionSkippingEvalEnabledCheck):
+
 2017-06-27  Ting-Wei Lan  <lant...@gmail.com>
 
         Add missing includes to fix compilation error on FreeBSD

Modified: trunk/Source/_javascript_Core/runtime/FunctionConstructor.cpp (218844 => 218845)


--- trunk/Source/_javascript_Core/runtime/FunctionConstructor.cpp	2017-06-27 21:35:25 UTC (rev 218844)
+++ trunk/Source/_javascript_Core/runtime/FunctionConstructor.cpp	2017-06-27 21:37:46 UTC (rev 218845)
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "FunctionConstructor.h"
 
+#include "Completion.h"
 #include "ExceptionHelpers.h"
 #include "FunctionPrototype.h"
 #include "JSAsyncFunction.h"
@@ -98,45 +99,79 @@
     switch (functionConstructionMode) {
     case FunctionConstructionMode::Function:
         structure = globalObject->functionStructure();
-        prefix = "{function ";
+        prefix = "function ";
         break;
     case FunctionConstructionMode::Generator:
         structure = globalObject->generatorFunctionStructure();
-        prefix = "{function *";
+        prefix = "function *";
         break;
     case FunctionConstructionMode::Async:
         structure = globalObject->asyncFunctionStructure();
-        prefix = "{async function ";
+        prefix = "async function ";
         break;
     }
 
+    auto checkBody = [&] (const String& body) {
+        // The spec mandates that the body parses a valid function body independent
+        // of the parameters.
+        String program = makeString("(", prefix, "(){\n", body, "\n})");
+        SourceCode source = makeSource(program, sourceOrigin, sourceURL, position);
+        JSValue exception;
+        checkSyntax(exec, source, &exception);
+        if (exception) {
+            scope.throwException(exec, exception);
+            return;
+        }
+    };
+
     // How we stringify functions is sometimes important for web compatibility.
     // See https://bugs.webkit.org/show_bug.cgi?id=24350.
     String program;
     if (args.isEmpty())
-        program = makeString(prefix, functionName.string(), "() {\n\n}}");
+        program = makeString("{", prefix, functionName.string(), "() {\n\n}}");
     else if (args.size() == 1) {
         auto body = args.at(0).toWTFString(exec);
         RETURN_IF_EXCEPTION(scope, nullptr);
-        program = makeString(prefix, functionName.string(), "() {\n", body, "\n}}");
+        checkBody(body);
+        RETURN_IF_EXCEPTION(scope, nullptr);
+        program = makeString("{", prefix, functionName.string(), "() {\n", body, "\n}}");
     } else {
         StringBuilder builder;
+        builder.append("{");
         builder.append(prefix);
         builder.append(functionName.string());
         builder.append('(');
+        StringBuilder parameterBuilder;
         auto viewWithString = args.at(0).toString(exec)->viewWithUnderlyingString(exec);
         RETURN_IF_EXCEPTION(scope, nullptr);
-        builder.append(viewWithString.view);
+        parameterBuilder.append(viewWithString.view);
         for (size_t i = 1; i < args.size() - 1; i++) {
-            builder.appendLiteral(", ");
+            parameterBuilder.appendLiteral(", ");
             auto viewWithString = args.at(i).toString(exec)->viewWithUnderlyingString(exec);
             RETURN_IF_EXCEPTION(scope, nullptr);
-            builder.append(viewWithString.view);
+            parameterBuilder.append(viewWithString.view);
         }
+
+        {
+            // The spec mandates that the parameters parse as a valid parameter list
+            // independent of the function body.
+            String program = makeString("(", prefix, "(", parameterBuilder.toString(), "){\n\n})");
+            SourceCode source = makeSource(program, sourceOrigin, sourceURL, position);
+            JSValue exception;
+            checkSyntax(exec, source, &exception);
+            if (exception) {
+                scope.throwException(exec, exception);
+                return nullptr;
+            }
+        }
+
+        builder.append(parameterBuilder);
         builder.appendLiteral(") {\n");
-        viewWithString = args.at(args.size() - 1).toString(exec)->viewWithUnderlyingString(exec);
+        auto body = args.at(args.size() - 1).toWTFString(exec);
         RETURN_IF_EXCEPTION(scope, nullptr);
-        builder.append(viewWithString.view);
+        checkBody(body);
+        RETURN_IF_EXCEPTION(scope, nullptr);
+        builder.append(body);
         builder.appendLiteral("\n}}");
         program = builder.toString();
     }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to