Discussion:
[njs] Fixed parsing of statements in if without newline.
Dmitry Volyntsev
2018-11-23 14:46:59 UTC
Permalink
details: https://hg.nginx.org/njs/rev/fa98656237f0
branches:
changeset: 670:fa98656237f0
user: Dmitry Volyntsev <***@nginx.com>
date: Fri Nov 23 17:46:30 2018 +0300
description:
Fixed parsing of statements in if without newline.

This fixes #8 issue on Github.

Thanks to ??? (Hong Zhi Dao)

diffstat:

njs/njs_parser.c | 75 ++++++++++++++++++++---------------------------
njs/test/njs_unit_test.c | 37 ++++++++++++++++++++---
2 files changed, 64 insertions(+), 48 deletions(-)

diffs (243 lines):

diff -r 185aa0986f71 -r fa98656237f0 njs/njs_parser.c
--- a/njs/njs_parser.c Fri Nov 23 14:30:24 2018 +0300
+++ b/njs/njs_parser.c Fri Nov 23 17:46:30 2018 +0300
@@ -311,12 +311,6 @@ njs_parser_statement(njs_vm_t *vm, njs_p
case NJS_TOKEN_FUNCTION:
return njs_parser_function_declaration(vm, parser);

- case NJS_TOKEN_RETURN:
- return njs_parser_return_statement(vm, parser);
-
- case NJS_TOKEN_VAR:
- return njs_parser_var_statement(vm, parser);
-
case NJS_TOKEN_IF:
return njs_parser_if_statement(vm, parser);

@@ -332,18 +326,9 @@ njs_parser_statement(njs_vm_t *vm, njs_p
case NJS_TOKEN_FOR:
return njs_parser_for_statement(vm, parser);

- case NJS_TOKEN_CONTINUE:
- return njs_parser_continue_statement(vm, parser);
-
- case NJS_TOKEN_BREAK:
- return njs_parser_break_statement(vm, parser);
-
case NJS_TOKEN_TRY:
return njs_parser_try_statement(vm, parser);

- case NJS_TOKEN_THROW:
- return njs_parser_throw_statement(vm, parser);
-
case NJS_TOKEN_SEMICOLON:
return njs_parser_token(parser);

@@ -360,7 +345,33 @@ njs_parser_statement(njs_vm_t *vm, njs_p
/* Fall through. */

default:
- token = njs_parser_expression(vm, parser, token);
+
+ switch (token) {
+ case NJS_TOKEN_VAR:
+ token = njs_parser_var_statement(vm, parser);
+ break;
+
+ case NJS_TOKEN_CONTINUE:
+ token = njs_parser_continue_statement(vm, parser);
+ break;
+
+ case NJS_TOKEN_BREAK:
+ token = njs_parser_break_statement(vm, parser);
+ break;
+
+ case NJS_TOKEN_RETURN:
+ token = njs_parser_return_statement(vm, parser);
+ break;
+
+ case NJS_TOKEN_THROW:
+ token = njs_parser_throw_statement(vm, parser);
+ break;
+
+ default:
+ token = njs_parser_expression(vm, parser, token);
+ break;
+ }
+
if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
return token;
}
@@ -781,11 +792,12 @@ njs_parser_return_statement(njs_vm_t *vm

switch (token) {

- case NJS_TOKEN_SEMICOLON:
case NJS_TOKEN_LINE_END:
return njs_parser_token(parser);

+ case NJS_TOKEN_SEMICOLON:
case NJS_TOKEN_CLOSE_BRACE:
+ case NJS_TOKEN_END:
return token;

default:
@@ -801,10 +813,6 @@ njs_parser_return_statement(njs_vm_t *vm
node->right = parser->node;
parser->node = node;

- if (token == NJS_TOKEN_SEMICOLON) {
- return njs_parser_token(parser);
- }
-
return token;
}
}
@@ -902,26 +910,7 @@ njs_parser_var_statement(njs_vm_t *vm, n

} while (token == NJS_TOKEN_COMMA);

- /*
- * A var statement must be terminated by semicolon,
- * or by a close curly brace or by the end of line.
- */
- switch (token) {
-
- case NJS_TOKEN_SEMICOLON:
- return njs_parser_token(parser);
-
- case NJS_TOKEN_CLOSE_BRACE:
- case NJS_TOKEN_END:
- return token;
-
- default:
- if (parser->lexer->prev_token == NJS_TOKEN_LINE_END) {
- return token;
- }
-
- return NJS_TOKEN_ILLEGAL;
- }
+ return token;
}


@@ -1516,10 +1505,10 @@ njs_parser_continue_statement(njs_vm_t *

switch (token) {

- case NJS_TOKEN_SEMICOLON:
case NJS_TOKEN_LINE_END:
return njs_parser_token(parser);

+ case NJS_TOKEN_SEMICOLON:
case NJS_TOKEN_CLOSE_BRACE:
case NJS_TOKEN_END:
return token;
@@ -1551,10 +1540,10 @@ njs_parser_break_statement(njs_vm_t *vm,

switch (token) {

- case NJS_TOKEN_SEMICOLON:
case NJS_TOKEN_LINE_END:
return njs_parser_token(parser);

+ case NJS_TOKEN_SEMICOLON:
case NJS_TOKEN_CLOSE_BRACE:
case NJS_TOKEN_END:
return token;
diff -r 185aa0986f71 -r fa98656237f0 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Fri Nov 23 14:30:24 2018 +0300
+++ b/njs/test/njs_unit_test.c Fri Nov 23 17:46:30 2018 +0300
@@ -2149,7 +2149,7 @@ static njs_unit_test_t njs_test[] =
nxt_string("123") },

{ nxt_string("(function(){ if(true) return 1 else return 0; })()"),
- nxt_string("1") },
+ nxt_string("SyntaxError: Unexpected token \"else\" in 1") },

{ nxt_string("(function(){ if(true) return 1; else return 0; })()"),
nxt_string("1") },
@@ -2163,6 +2163,9 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("(function(){ if(true) return 1\n;\n else return 0; })()"),
nxt_string("1") },

+ { nxt_string("function f(n) {if (n) throw 'foo' else return 1}; f(0)"),
+ nxt_string("SyntaxError: Unexpected token \"else\" in 1") },
+
{ nxt_string("function f(n) {if (n)\n throw 'foo'\nelse return 1}; f(0)"),
nxt_string("1") },

@@ -2172,6 +2175,24 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("function f(n) {if (n == 1) throw 'foo'\nelse if (n == 2) return 1}; f(2)"),
nxt_string("1") },

+ { nxt_string("(function(){ for (var p in [1] ){ if (1) break else return 0; }})()"),
+ nxt_string("SyntaxError: Unexpected token \"else\" in 1") },
+
+ { nxt_string("(function(){ for (var p in [1] ){ if (1) break\n else return 0; }})()"),
+ nxt_string("undefined") },
+
+ { nxt_string("(function(){ for (var p in [1] ){ if (1) break; else return 0; }})()"),
+ nxt_string("undefined") },
+
+ { nxt_string("(function(){ for (var p in [1] ){ if (1) continue else return 0; }})()"),
+ nxt_string("SyntaxError: Unexpected token \"else\" in 1") },
+
+ { nxt_string("(function(){ for (var p in [1] ){ if (1) continue\n else return 0; }})()"),
+ nxt_string("undefined") },
+
+ { nxt_string("(function(){ for (var p in [1] ){ if (1) continue; else return 0; }})()"),
+ nxt_string("undefined") },
+
/* do while. */

{ nxt_string("do { break } if (false)"),
@@ -5259,6 +5280,12 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("function f() { return 1\n 2 } f()"),
nxt_string("1") },

+ { nxt_string("(function f() { return 2.toString(); })()"),
+ nxt_string("SyntaxError: Unexpected token \"toString\" in 1") },
+
+ { nxt_string("(function f() { return 2..toString(); })()"),
+ nxt_string("2") },
+
{ nxt_string("function f(a) { if (a) return 'OK' } f(1)+f(0)"),
nxt_string("OKundefined") },

@@ -5295,7 +5322,7 @@ static njs_unit_test_t njs_test[] =

{ nxt_string("function f(a) {"
" if (a > 1)"
- " return a * f(a - 1)"
+ " return a * f(a - 1)\n"
" return 1"
"}"
"f(10)"),
@@ -5420,7 +5447,7 @@ static njs_unit_test_t njs_test[] =

{ nxt_string("function fibo(n) {"
" if (n > 1)"
- " return fibo(n-1) + fibo(n-2)"
+ " return fibo(n-1) + fibo(n-2)\n"
" return 1"
"}"
"fibo(10)"),
@@ -5428,7 +5455,7 @@ static njs_unit_test_t njs_test[] =

{ nxt_string("function fibo(n) {"
" if (n > 1)"
- " return fibo(n-1) + fibo(n-2)"
+ " return fibo(n-1) + fibo(n-2)\n"
" return '.'"
"}"
"fibo(10).length"),
@@ -5436,7 +5463,7 @@ static njs_unit_test_t njs_test[] =

{ nxt_string("function fibo(n) {"
" if (n > 1)"
- " return fibo(n-1) + fibo(n-2)"
+ " return fibo(n-1) + fibo(n-2)\n"
" return 1"
"}"
"fibo('10')"),

Loading...