LibJS: Disallow escape sequence/line continuation in use strict directive

https://tc39.es/ecma262/#sec-directive-prologues-and-the-use-strict-directive

A Use Strict Directive is an ExpressionStatement in a Directive Prologue
whose StringLiteral is either of the exact code point sequences
"use strict" or 'use strict'. A Use Strict Directive may not contain an
EscapeSequence or LineContinuation.
This commit is contained in:
Linus Groh 2020-10-24 13:50:59 +01:00 committed by Andreas Kling
parent 4fb96afafc
commit 2adcabb6b3
Notes: sideshowbarker 2024-07-19 01:46:26 +09:00
2 changed files with 53 additions and 4 deletions

View file

@ -861,6 +861,8 @@ NonnullRefPtr<StringLiteral> Parser::parse_string_literal(Token token, bool in_t
syntax_error(message, token.line_number(), token.line_column());
}
auto is_use_strict_directive = token.value() == "'use strict'" || token.value() == "\"use strict\"";
// It is possible for string literals to precede a Use Strict Directive that places the
// enclosing code in strict mode, and implementations must take care to not use this
// extended definition of EscapeSequence with such literals. For example, attempting to
@ -868,15 +870,14 @@ NonnullRefPtr<StringLiteral> Parser::parse_string_literal(Token token, bool in_t
//
// function invalid() { "\7"; "use strict"; }
if (m_parser_state.m_string_legacy_octal_escape_sequence_in_scope && string == "use strict")
if (m_parser_state.m_string_legacy_octal_escape_sequence_in_scope && is_use_strict_directive)
syntax_error("Octal escape sequence in string literal not allowed in strict mode");
if (m_parser_state.m_use_strict_directive == UseStrictDirectiveState::Looking) {
if (string == "use strict" && token.type() != TokenType::TemplateLiteralString) {
if (is_use_strict_directive)
m_parser_state.m_use_strict_directive = UseStrictDirectiveState::Found;
} else {
else
m_parser_state.m_use_strict_directive = UseStrictDirectiveState::None;
}
}
return create_ast_node<StringLiteral>(string);

View file

@ -0,0 +1,48 @@
test("valid 'use strict; directive", () => {
expect(
(() => {
"use strict";
return isStrictMode();
})()
).toBeTrue();
expect(
(() => {
'use strict';
return isStrictMode();
})()
).toBeTrue();
});
test("invalid 'use strict; directive", () => {
expect(
(() => {
" use strict ";
return isStrictMode();
})()
).toBeFalse();
expect(
(() => {
`use strict`;
return isStrictMode();
})()
).toBeFalse();
expect(
(() => {
"use\
strict";
return isStrictMode();
})()
).toBeFalse();
expect(
(() => {
"use\ strict";
return isStrictMode();
})()
).toBeFalse();
expect(
(() => {
"use \163trict";
return isStrictMode();
})()
).toBeFalse();
});