From: Dmitry Volyntsev Date: Tue, 1 Sep 2026 01:31:20 +0000 (-0700) Subject: Parser: report an invalid "for-in" target as a SyntaxError X-Git-Tag: 1.0.2~88 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=ab709e37d0509c03a8ee71d67b6798f0bbbc5641;p=njs.git Parser: report an invalid "for-in" target as a SyntaxError Previously, an invalid for-in target was a ReferenceError when the initializer happened to parse as a LeftHandSideExpression and a SyntaxError otherwise, so the same target changed class once parenthesized: for (a = 1 in {}); SyntaxError for ((a = 1) in {}); ReferenceError The fix is to report a SyntaxError for both, as the specification and V8 do. The type is observable through Function(), so this is a compatibility change. njs keeps ReferenceError for invalid assignment targets elsewhere. --- diff --git a/src/njs_parser.c b/src/njs_parser.c index de447acd..010a9b4e 100644 --- a/src/njs_parser.c +++ b/src/njs_parser.c @@ -5832,12 +5832,12 @@ njs_parser_for_expression_map_continue(njs_parser_t *parser, if (!njs_parser_is_lvalue(parser->node)) { text = (njs_str_t *) parser->target; - njs_parser_ref_error(parser, "Invalid left-hand side \"%V\" " - "in for-in statement", text); - njs_mp_free(parser->vm->mem_pool, text); - return NJS_DONE; + njs_parser_syntax_error(parser, + "Invalid left-hand side in for-loop"); + + return NJS_ERROR; } parser->node = njs_parser_lvalue_ref(parser->node); diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 924dd943..3f7a56a6 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -3403,8 +3403,38 @@ static njs_unit_test_t njs_test[] = /* for in. */ + /* An invalid for-in target is a SyntaxError, parenthesized or not. */ + { njs_str("for (null in undefined);"), - njs_str("ReferenceError: Invalid left-hand side \"null\" in for-in statement") }, + njs_str("SyntaxError: Invalid left-hand side in for-loop") }, + + { njs_str("for ((null) in undefined);"), + njs_str("SyntaxError: Invalid left-hand side in for-loop") }, + + { njs_str("for (1 in {});"), + njs_str("SyntaxError: Invalid left-hand side in for-loop") }, + + { njs_str("for (this in {});"), + njs_str("SyntaxError: Invalid left-hand side in for-loop") }, + + { njs_str("for (function(){} in x);"), + njs_str("SyntaxError: Invalid left-hand side in for-loop") }, + + { njs_str("for ((a = 1) in {});"), + njs_str("SyntaxError: Invalid left-hand side in for-loop") }, + + { njs_str("for ((x => x) in {});"), + njs_str("SyntaxError: Invalid left-hand side in for-loop") }, + + { njs_str("var r; try { Function('for (null in undefined);') }" + "catch (e) { r = e.name } r"), + njs_str("SyntaxError") }, + + { njs_str("var d = {}; for (d.a in {x:1}); d.a"), + njs_str("x") }, + + { njs_str("var d = {}; for ((d.a) in {x:1}); d.a"), + njs_str("x") }, { njs_str("for (var a, b in []);"), njs_str("SyntaxError: Unexpected token \"in\"") },