Skip to content

Commit

Permalink
Allow 'undefined' in let or const declaration
Browse files Browse the repository at this point in the history
Except at the global scope of a classic script because... who knows,
that's just how it is.

Fixes: #633
  • Loading branch information
bnoordhuis committed Oct 29, 2024
1 parent 56e5ffa commit 7f919d2
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 4 deletions.
14 changes: 11 additions & 3 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -22707,9 +22707,17 @@ static __exception int js_define_var(JSParseState *s, JSAtom name, int tok)
&& fd->is_strict_mode) {
return js_parse_error(s, "invalid variable name in strict mode");
}
if ((name == JS_ATOM_let || name == JS_ATOM_undefined)
&& (tok == TOK_LET || tok == TOK_CONST)) {
return js_parse_error(s, "invalid lexical variable name");
if (tok == TOK_LET || tok == TOK_CONST) {
if (name == JS_ATOM_let)
return js_parse_error(s, "invalid lexical variable name");
// |undefined| is allowed as an identifier except at the global
// scope of a classic script; sloppy or strict doesn't matter
if (name == JS_ATOM_undefined
&& fd->scope_level == 1
&& fd->is_global_var
&& !fd->module) {
return js_parse_error(s, "'undefined' already declared");
}
}
switch(tok) {
case TOK_LET:
Expand Down
6 changes: 5 additions & 1 deletion run-test262.c
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,7 @@ int run_test(const char *filename, int *msec)
char *error_type;
int ret, eval_flags, use_strict, use_nostrict;
BOOL is_negative, is_nostrict, is_onlystrict, is_async, is_module, skip;
BOOL detect_module = TRUE;
BOOL can_block;
namelist_t include_list = { 0 }, *ip = &include_list;

Expand Down Expand Up @@ -1838,6 +1839,9 @@ int run_test(const char *filename, int *msec)
is_async = TRUE;
skip |= skip_async;
}
else if (str_equal(option, "qjs:no-detect-module")) {
detect_module = FALSE;
}
else if (str_equal(option, "module")) {
is_module = TRUE;
skip |= skip_module;
Expand Down Expand Up @@ -1920,7 +1924,7 @@ int run_test(const char *filename, int *msec)
atomic_inc(&test_skipped);
ret = -2;
} else {
if (local) {
if (local && detect_module) {
is_module = JS_DetectModule(buf, buf_len);
}
if (is_module) {
Expand Down
7 changes: 7 additions & 0 deletions tests/bug633/0.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*---
flags: [qjs:no-detect-module]
negative:
phase: parse
type: SyntaxError
---*/
const undefined = 42 // SyntaxError at global scope
4 changes: 4 additions & 0 deletions tests/bug633/1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*---
flags: [qjs:no-detect-module, module]
---*/
const undefined = 42 // not a SyntaxError at toplevel module scope
4 changes: 4 additions & 0 deletions tests/bug633/2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*---
flags: [qjs:no-detect-module]
---*/
{ const undefined = 42 } // not a SyntaxError, not at global scope
4 changes: 4 additions & 0 deletions tests/bug633/3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*---
flags: [qjs:no-detect-module]
---*/
;(function() { const undefined = 42 })() // not a SyntaxError, not at global scope

0 comments on commit 7f919d2

Please sign in to comment.