[njs] Fixed parsing of statements in if without newline.

Dmitry Volyntsev xeioex at nginx.com
Fri Nov 23 14:46:59 UTC 2018


details:   https://hg.nginx.org/njs/rev/fa98656237f0
branches:  
changeset: 670:fa98656237f0
user:      Dmitry Volyntsev <xeioex at 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')"),


More information about the nginx-devel mailing list