1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-17 12:55:07 +00:00
serenity/Libraries/LibJS/Tests/parser-line-terminators.js
Linus Groh a10d09faba LibJS: Tweak generated source in 'new Function()' to match ES 2015 spec
ES 5(.1) described parsing of the function body string as:

https://www.ecma-international.org/ecma-262/5.1/#sec-15.3.2.1

7. If P is not parsable as a FormalParameterList[opt] then throw a SyntaxError exception.
8. If body is not parsable as FunctionBody then throw a SyntaxError exception.

We implemented it as building the source string of a complete function
and feeding that to the parser, with the same outcome. ES 2015+ does
exactly that, but with newlines at certain positions:

https://tc39.es/ecma262/#sec-createdynamicfunction

16. Let bodyString be the string-concatenation of 0x000A (LINE FEED), ? ToString(bodyArg), and 0x000A (LINE FEED).
17. Let prefix be the prefix associated with kind in Table 49.
18. Let sourceString be the string-concatenation of prefix, " anonymous(", P, 0x000A (LINE FEED), ") {", bodyString, and "}".

This patch updates the generated source string to match these
requirements. This will make certain edge cases work, e.g.
'new Function("-->")', where the user supplied input must be placed on
its own line to be valid syntax.
2020-10-29 22:27:55 +01:00

66 lines
1.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
These tests deliberately produce syntax errors to check what line the parser thinks we're on.
Note that line numbers are higher than you might expect as the parsed code is:
function anonymous(
) {
<code>
}
⚠ PLEASE MAKE SURE TO NOT LET YOUR EDITOR REMOVE THE LS/PS LINE TERMINATORS!
*/
test("LINE FEED is a line terminator", () => {
expect(() => {
Function("\n\n@");
}).toThrowWithMessage(SyntaxError, "line: 5, column: 1");
});
test("CARRIAGE RETURN is a line terminator", () => {
expect(() => {
Function("\r\r@");
}).toThrowWithMessage(SyntaxError, "line: 5, column: 1");
});
test("LINE SEPARATOR is a line terminator", () => {
expect(() => {
Function("@");
}).toThrowWithMessage(SyntaxError, "line: 5, column: 1");
});
test("PARAGRAPH SEPARATOR is a line terminator", () => {
expect(() => {
Function("@");
}).toThrowWithMessage(SyntaxError, "line: 5, column: 1");
});
test("CR LF is counted as only one line terminator", () => {
expect(() => {
Function("\r\n\r\n@");
}).toThrowWithMessage(SyntaxError, "line: 5, column: 1");
});
test("LF/CR are not allowed in string literal", () => {
expect(() => {
Function(`"
"`);
}).toThrowWithMessage(SyntaxError, "Unexpected token UnterminatedStringLiteral");
});
test("LS/PS are allowed in string literal", () => {
expect(`""`).toEval();
expect(`""`).toEval();
});
test("line terminators can be mixed (but please don't)", () => {
expect(() => {
Function("\r\r\n\n\r@");
}).toThrowWithMessage(SyntaxError, "line: 9, column: 1");
});
test("all line terminators are valid for line continuations", () => {
expect(Function('return "a\\\nb"')()).toBe("ab");
expect(Function('return "a\\\rb"')()).toBe("ab");
expect(Function('return "a\\b"')()).toBe("ab");
expect(Function('return "a\\b"')()).toBe("ab");
});