]> git.kaiwu.me - njs.git/commitdiff
Segfault is fixed when the last return in function is terminated
authorIgor Sysoev <igor@sysoev.ru>
Tue, 12 Jan 2016 16:47:29 +0000 (19:47 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Tue, 12 Jan 2016 16:47:29 +0000 (19:47 +0300)
by semicolon.

njs/njs_parser.c
njs/test/njs_unit_test.c

index 3a053a6777b4188bc1a5cca8b0e86ca96e7358b2..82138bcc74e2bb744c703017bd77bd2db3b3d8ad 100644 (file)
@@ -447,7 +447,7 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_function_lambda_t *lambda,
     njs_index_t        index;
     njs_parser_t       *parser;
     njs_variable_t     *arg;
-    njs_parser_node_t  *node, *body;
+    njs_parser_node_t  *node, *body, *last;
 
     parser = lambda->u.parser;
 
@@ -516,14 +516,27 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_function_lambda_t *lambda,
         return token;
     }
 
-    /*
-     * There is no function body or the last function body statement is not
-     * "return" statement.  If function has body then the body->right node is
-     * always present and it is a NJS_TOKEN_STATEMENT link node.
-     */
+    last = NULL;
     body = parser->node;
 
-    if (body == NULL || body->right->token != NJS_TOKEN_RETURN) {
+    if (body != NULL) {
+        /* Take the last function body statement. */
+        last = body->right;
+
+        if (last == NULL) {
+            /*
+             * The last statement is terminated by semicolon.
+             * Take the last statement itself.
+             */
+            last = body->left;
+        }
+    }
+
+    if (last == NULL || last->token != NJS_TOKEN_RETURN) {
+        /*
+         * There is no function body or the last function body
+         * body statement is not "return" statement.
+         */
         node = njs_parser_node_alloc(vm);
         if (nxt_slow_path(node == NULL)) {
             return NJS_TOKEN_ERROR;
index 36245ef4285ff6577d84ac959c67993880dc9368..cc269072e2a9eb94af7acbaef9cb550b57517e5b 100644 (file)
@@ -2569,6 +2569,45 @@ static njs_unit_test_t  njs_test[] =
 
     /* Functions. */
 
+    { nxt_string("function f() { } f()"),
+      nxt_string("undefined") },
+
+    { nxt_string("function f() { ; } f()"),
+      nxt_string("undefined") },
+
+    { nxt_string("function f() { ;; } f()"),
+      nxt_string("undefined") },
+
+    { nxt_string("function f() { return } f()"),
+      nxt_string("undefined") },
+
+    { nxt_string("function f() { return; } f()"),
+      nxt_string("undefined") },
+
+    { nxt_string("function f() { return;; } f()"),
+      nxt_string("undefined") },
+
+    { nxt_string("function f() { return 1 } f()"),
+      nxt_string("1") },
+
+    { nxt_string("function f() { return 1; } f()"),
+      nxt_string("1") },
+
+    { nxt_string("function f() { return 1;; } f()"),
+      nxt_string("1") },
+
+    { nxt_string("function f() { return 1\n 2 } f()"),
+      nxt_string("1") },
+
+    { nxt_string("function f(a) { if (a) return 'OK' } f(1)+f(0)"),
+      nxt_string("OKundefined") },
+
+    { nxt_string("function f(a) { if (a) return 'OK'; } f(1)+f(0)"),
+      nxt_string("OKundefined") },
+
+    { nxt_string("function f(a) { if (a) return 'OK';; } f(1)+f(0)"),
+      nxt_string("OKundefined") },
+
     { nxt_string("var a = 1; a()"),
       nxt_string("TypeError") },
 
@@ -2798,6 +2837,9 @@ static njs_unit_test_t  njs_test[] =
                  "f.apply(5, [1, 2], 3)"),
       nxt_string("8") },
 
+    { nxt_string("var a = function() { return 1 } + ''; a"),
+      nxt_string("[object Function]") },
+
     { nxt_string("''.concat.call()"),
       nxt_string("TypeError") },