Skip to content

Commit 30ad9bf

Browse files
committed
fix(parser): reject statement keywords in expressions
1 parent a950394 commit 30ad9bf

3 files changed

Lines changed: 59 additions & 1 deletion

File tree

src/compiler.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6860,7 +6860,9 @@ impl<'source> Parser<'source> {
68606860
)));
68616861
}
68626862
TokenKind::Keyword(
6863-
keyword @ (Keyword::Else
6863+
keyword @ (Keyword::If
6864+
| Keyword::For
6865+
| Keyword::Else
68646866
| Keyword::In
68656867
| Keyword::Case
68666868
| Keyword::Default

src/compiler/tests.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10300,6 +10300,30 @@ fn always_reserved_words_use_quickjs_syntax_diagnostics() {
1030010300
}
1030110301
}
1030210302

10303+
#[test]
10304+
fn statement_keywords_in_primary_expression_use_quickjs_syntax_diagnostics() {
10305+
for (source, keyword, column) in [
10306+
("({[if (0) 0;]})", "if", 4),
10307+
("[for (x of [1]) x]", "for", 2),
10308+
] {
10309+
let error = compile_unlinked_script(source).unwrap_err();
10310+
assert_eq!(error.kind(), ErrorKind::Syntax, "{source:?}: {error}");
10311+
assert_eq!(
10312+
error.message(),
10313+
format!("unexpected token in expression: '{keyword}'"),
10314+
"{source:?}"
10315+
);
10316+
let span = error
10317+
.span()
10318+
.unwrap_or_else(|| panic!("missing syntax span for {source:?}"));
10319+
assert_eq!(
10320+
(span.start.line, span.start.column),
10321+
(1, column),
10322+
"{source:?}"
10323+
);
10324+
}
10325+
}
10326+
1030310327
#[test]
1030410328
fn reserved_property_names_and_import_frontiers_remain_distinct() {
1030510329
for source in [

tests/oracle_function_constructor.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,22 @@ try {
160160
text(error.lineNumber) + ":" + text(error.columnNumber) + "|" +
161161
firstTwoFrames(error.stack));
162162
}
163+
try {
164+
Function("({[if (0) 0;]})");
165+
print("computed-if-error=missing");
166+
} catch (error) {
167+
print("computed-if-error=" + error.name + ":" + error.message + "|" +
168+
text(error.fileName) + ":" + text(error.lineNumber) + ":" +
169+
text(error.columnNumber) + "|" + firstTwoFrames(error.stack));
170+
}
171+
try {
172+
Function("[for (x of [1]) x]");
173+
print("array-for-error=missing");
174+
} catch (error) {
175+
print("array-for-error=" + error.name + ":" + error.message + "|" +
176+
text(error.fileName) + ":" + text(error.lineNumber) + ":" +
177+
text(error.columnNumber) + "|" + firstTwoFrames(error.stack));
178+
}
163179
"#;
164180

165181
#[test]
@@ -537,6 +553,22 @@ fn rust_observations(mode: DebugInfoMode) -> Vec<String> {
537553
&[string("null"), string("return 1")],
538554
&mut output,
539555
);
556+
observe_constructor_syntax_error(
557+
&runtime,
558+
&mut context,
559+
&constructor,
560+
"computed-if-error",
561+
&[string("({[if (0) 0;]})")],
562+
&mut output,
563+
);
564+
observe_constructor_syntax_error(
565+
&runtime,
566+
&mut context,
567+
&constructor,
568+
"array-for-error",
569+
&[string("[for (x of [1]) x]")],
570+
&mut output,
571+
);
540572

541573
output
542574
}

0 commit comments

Comments
 (0)