[njs] Parser: correctly fixing closing brace unwinding for invalid syntax.
Alexander Borisov
alexander.borisov at nginx.com
Sat Jun 6 15:16:27 UTC 2020
details: https://hg.nginx.org/njs/rev/857c2166d10b
branches:
changeset: 1427:857c2166d10b
user: Alexander Borisov <alexander.borisov at nginx.com>
date: Sat Jun 06 18:15:07 2020 +0300
description:
Parser: correctly fixing closing brace unwinding for invalid syntax.
The issue was introduced in 86f55a7dc4a4.
Previous attempts to catch unprocessed token in ea1754b79e7a and 61dce54ce3d5
were misplaced.
diffstat:
src/njs_parser.c | 78 ++++++++++-----------------------
src/test/njs_unit_test.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 133 insertions(+), 53 deletions(-)
diffs (367 lines):
diff -r bc79f5c80452 -r 857c2166d10b src/njs_parser.c
--- a/src/njs_parser.c Thu Jun 04 17:26:01 2020 +0300
+++ b/src/njs_parser.c Sat Jun 06 18:15:07 2020 +0300
@@ -1154,7 +1154,7 @@ njs_parser_primary_expression_test(njs_p
njs_parser_next(parser, njs_parser_expression);
- return njs_parser_after(parser, current, NULL, 1,
+ return njs_parser_after(parser, current, NULL, 0,
njs_parser_close_parenthesis);
default:
@@ -3137,10 +3137,6 @@ njs_parser_expression_node(njs_parser_t
{
njs_parser_node_t *node;
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
if (parser->target != NULL) {
parser->target->right = parser->node;
parser->target->right->dest = parser->target;
@@ -3163,7 +3159,7 @@ njs_parser_expression_node(njs_parser_t
njs_lexer_consume_token(parser->lexer, 1);
- return njs_parser_after(parser, current, node, 0, after);
+ return njs_parser_after(parser, current, node, 1, after);
}
@@ -3204,7 +3200,7 @@ njs_parser_update_expression(njs_parser_
njs_lexer_consume_token(parser->lexer, 1);
njs_parser_next(parser, njs_parser_left_hand_side_expression);
- return njs_parser_after(parser, current, node, 0,
+ return njs_parser_after(parser, current, node, 1,
njs_parser_update_expression_unary);
}
@@ -3267,10 +3263,6 @@ static njs_int_t
njs_parser_update_expression_unary(njs_parser_t *parser,
njs_lexer_token_t *token, njs_queue_link_t *current)
{
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
if (!njs_parser_is_lvalue(parser->node)) {
njs_parser_ref_error(parser,
"Invalid left-hand side in prefix operation");
@@ -3354,7 +3346,7 @@ njs_parser_unary_expression(njs_parser_t
njs_lexer_consume_token(parser->lexer, 1);
- return njs_parser_after(parser, current, node, 0,
+ return njs_parser_after(parser, current, node, 1,
njs_parser_unary_expression_next);
}
@@ -3382,10 +3374,6 @@ njs_parser_unary_expression_next(njs_par
njs_token_type_t type;
njs_parser_node_t *node;
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
type = parser->target->token_type;
node = parser->node;
@@ -3464,10 +3452,6 @@ njs_parser_exponentiation_expression_mat
{
njs_parser_node_t *node;
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
if (parser->target != NULL) {
parser->target->right = parser->node;
parser->target->right->dest = parser->target;
@@ -3494,7 +3478,7 @@ njs_parser_exponentiation_expression_mat
njs_parser_next(parser, njs_parser_exponentiation_expression);
- return njs_parser_after(parser, current, node, 0,
+ return njs_parser_after(parser, current, node, 1,
njs_parser_exponentiation_expression_match);
}
@@ -3520,10 +3504,6 @@ njs_parser_multiplicative_expression_mat
njs_parser_node_t *node;
njs_vmcode_operation_t operation;
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
if (parser->target != NULL) {
parser->target->right = parser->node;
parser->target->right->dest = parser->target;
@@ -3561,7 +3541,7 @@ njs_parser_multiplicative_expression_mat
njs_parser_next(parser, njs_parser_exponentiation_expression);
- return njs_parser_after(parser, current, node, 0,
+ return njs_parser_after(parser, current, node, 1,
njs_parser_multiplicative_expression_match);
}
@@ -3587,10 +3567,6 @@ njs_parser_additive_expression_match(njs
njs_parser_node_t *node;
njs_vmcode_operation_t operation;
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
if (parser->target != NULL) {
parser->target->right = parser->node;
parser->target->right->dest = parser->target;
@@ -3624,7 +3600,7 @@ njs_parser_additive_expression_match(njs
njs_parser_next(parser, njs_parser_multiplicative_expression);
- return njs_parser_after(parser, current, node, 0,
+ return njs_parser_after(parser, current, node, 1,
njs_parser_additive_expression_match);
}
@@ -3650,10 +3626,6 @@ njs_parser_shift_expression_match(njs_pa
njs_parser_node_t *node;
njs_vmcode_operation_t operation;
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
if (parser->target != NULL) {
parser->target->right = parser->node;
parser->target->right->dest = parser->target;
@@ -3691,7 +3663,7 @@ njs_parser_shift_expression_match(njs_pa
njs_parser_next(parser, njs_parser_additive_expression);
- return njs_parser_after(parser, current, node, 0,
+ return njs_parser_after(parser, current, node, 1,
njs_parser_shift_expression_match);
}
@@ -3717,10 +3689,6 @@ njs_parser_relational_expression_match(n
njs_parser_node_t *node;
njs_vmcode_operation_t operation;
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
if (parser->target != NULL) {
parser->target->right = parser->node;
parser->target->right->dest = parser->target;
@@ -3770,7 +3738,7 @@ njs_parser_relational_expression_match(n
njs_parser_next(parser, njs_parser_shift_expression);
- return njs_parser_after(parser, current, node, 0,
+ return njs_parser_after(parser, current, node, 1,
njs_parser_relational_expression_match);
}
@@ -3796,10 +3764,6 @@ njs_parser_equality_expression_match(njs
njs_parser_node_t *node;
njs_vmcode_operation_t operation;
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
if (parser->target != NULL) {
parser->target->right = parser->node;
parser->target->right->dest = parser->target;
@@ -3841,7 +3805,7 @@ njs_parser_equality_expression_match(njs
njs_parser_next(parser, njs_parser_relational_expression);
- return njs_parser_after(parser, current, node, 0,
+ return njs_parser_after(parser, current, node, 1,
njs_parser_equality_expression_match);
}
@@ -3979,10 +3943,6 @@ njs_parser_coalesce_expression(njs_parse
njs_token_type_t type;
njs_parser_node_t *node;
- if (parser->ret != NJS_OK) {
- return njs_parser_failed(parser);
- }
-
node = parser->node;
if (parser->target != NULL) {
@@ -4016,7 +3976,7 @@ njs_parser_coalesce_expression(njs_parse
njs_lexer_consume_token(parser->lexer, 1);
njs_parser_next(parser, njs_parser_bitwise_OR_expression);
- return njs_parser_after(parser, current, node, 0,
+ return njs_parser_after(parser, current, node, 1,
njs_parser_coalesce_expression);
}
@@ -4657,7 +4617,7 @@ njs_parser_block_statement(njs_parser_t
njs_parser_next(parser, njs_parser_statement_list);
- return njs_parser_after(parser, current, target, 1,
+ return njs_parser_after(parser, current, target, 0,
njs_parser_block_statement_close_brace);
}
@@ -4689,6 +4649,10 @@ njs_parser_block_statement_close_brace(n
{
njs_parser_node_t *node;
+ if (parser->ret != NJS_OK) {
+ return njs_parser_failed(parser);
+ }
+
if (token->type != NJS_TOKEN_CLOSE_BRACE) {
return njs_parser_failed(parser);
}
@@ -4728,7 +4692,15 @@ njs_parser_statement_list_next(njs_parse
njs_queue_link_t *current)
{
if (parser->ret != NJS_OK) {
- parser->node = parser->target;
+ if (token->type != NJS_TOKEN_CLOSE_BRACE) {
+ parser->node = parser->target;
+ return njs_parser_stack_pop(parser);
+ }
+
+ return njs_parser_failed(parser);
+ }
+
+ if (token->type == NJS_TOKEN_CLOSE_BRACE) {
return njs_parser_stack_pop(parser);
}
diff -r bc79f5c80452 -r 857c2166d10b src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Thu Jun 04 17:26:01 2020 +0300
+++ b/src/test/njs_unit_test.c Sat Jun 06 18:15:07 2020 +0300
@@ -16861,6 +16861,114 @@ static njs_unit_test_t njs_test[] =
{ njs_str("{{}{1>>}"),
njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}{r=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}{var a = }"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}T=>}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a = b +}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a = b -}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a = b *}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a = b /}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a = b %}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a = b++}"),
+ njs_str("ReferenceError: \"a\" is not defined in 1") },
+
+ { njs_str("{{}a = b--}"),
+ njs_str("ReferenceError: \"a\" is not defined in 1") },
+
+ { njs_str("{{}a =}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a +=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a -=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a *=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a /=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a %=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a ===}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a ==}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a !=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a !==}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a >}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a <}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a <=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a &&}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a ||}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a ??}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a &}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a |}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a ^}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a <<}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}a >>}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}new}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}delete}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}void}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{}typeof}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+
+ { njs_str("{{} ({a: 1, b: {}\n}\n})\n}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 3") },
};
More information about the nginx-devel
mailing list