[njs] Segfaults in the delete operator have been fixed.

Igor Sysoev igor at sysoev.ru
Tue Oct 11 14:52:05 UTC 2016


details:   http://hg.nginx.org/njs/rev/f8cc880d9b9b
branches:  
changeset: 195:f8cc880d9b9b
user:      Igor Sysoev <igor at sysoev.ru>
date:      Tue Oct 11 17:44:01 2016 +0300
description:
Segfaults in the delete operator have been fixed.

diffstat:

 njs/njs_generator.c         |  77 ---------------------------------------------
 njs/njs_parser_expression.c |  34 +++++++++++++------
 njs/njs_vm.c                |   2 -
 njs/test/njs_unit_test.c    |  27 +++++++++-----
 4 files changed, 40 insertions(+), 100 deletions(-)

diffs (225 lines):

diff -r da89f264af94 -r f8cc880d9b9b njs/njs_generator.c
--- a/njs/njs_generator.c	Tue Oct 11 17:04:28 2016 +0300
+++ b/njs/njs_generator.c	Tue Oct 11 17:44:01 2016 +0300
@@ -21,7 +21,6 @@
 #include <njs_variable.h>
 #include <njs_parser.h>
 #include <string.h>
-#include <stdio.h>
 
 
 static nxt_int_t njs_generator(njs_vm_t *vm, njs_parser_t *parser,
@@ -76,8 +75,6 @@ static nxt_int_t njs_generate_function(n
     njs_parser_node_t *node);
 static nxt_int_t njs_generate_regexp(njs_vm_t *vm, njs_parser_t *parser,
     njs_parser_node_t *node);
-static nxt_int_t njs_generate_delete(njs_vm_t *vm, njs_parser_t *parser,
-    njs_parser_node_t *node);
 static nxt_int_t njs_generate_test_jump_expression(njs_vm_t *vm,
     njs_parser_t *parser, njs_parser_node_t *node);
 static nxt_int_t njs_generate_3addr_operation(njs_vm_t *vm,
@@ -232,8 +229,6 @@ njs_generator(njs_vm_t *vm, njs_parser_t
         return njs_generate_test_jump_expression(vm, parser, node);
 
     case NJS_TOKEN_DELETE:
-        return njs_generate_delete(vm, parser, node);
-
     case NJS_TOKEN_VOID:
     case NJS_TOKEN_TYPEOF:
     case NJS_TOKEN_UNARY_PLUS:
@@ -1578,78 +1573,6 @@ njs_generate_regexp(njs_vm_t *vm, njs_pa
 
 
 static nxt_int_t
-njs_generate_delete(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node)
-{
-    double              n;
-    nxt_int_t           ret;
-    njs_index_t         index;
-    njs_parser_node_t   *operand;
-    njs_vmcode_2addr_t  *delete;
-
-    operand = node->left;
-
-    /*
-     * The "delete" operator returns "false" for "undefined", "NaN", and
-     * "Infinity" constants but not for values, expressions and "-Infinity".
-     */
-
-    switch (operand->token) {
-
-    case NJS_TOKEN_NAME:
-        if (operand->u.variable->state == NJS_VARIABLE_DECLARED) {
-            index = njs_value_index(vm, parser, &njs_value_false);
-            goto done;
-        }
-
-        /* A property of the global object. */
-
-        njs_generate_code(parser, njs_vmcode_2addr_t, delete);
-        delete->code.operation = njs_vmcode_delete;
-        delete->code.operands = NJS_VMCODE_2OPERANDS;
-        delete->code.retval = NJS_VMCODE_RETVAL;
-        delete->dst = njs_generator_node_temp_index_get(parser, node);
-        delete->src = operand->u.variable->index;
-
-        return NXT_OK;
-
-    case NJS_TOKEN_NUMBER:
-        n = operand->u.value.data.u.number;
-
-        if (!njs_is_nan(n) && !(njs_is_infinity(n) && n > 0.0)) {
-            break;
-        }
-
-        /* Fall through. */
-
-    case NJS_TOKEN_UNDEFINED:
-        index = njs_value_index(vm, parser, &njs_value_false);
-        goto done;
-
-    default:
-        ret = njs_generator(vm, parser, operand);
-        if (nxt_slow_path(ret != NXT_OK)) {
-            return ret;
-        }
-
-        ret = njs_generator_node_index_release(vm, parser, operand);
-        if (nxt_slow_path(ret != NXT_OK)) {
-            return ret;
-        }
-
-        break;
-    }
-
-    index = njs_value_index(vm, parser, &njs_value_true);
-
-done:
-
-    node->index = index;
-
-    return NXT_OK;
-}
-
-
-static nxt_int_t
 njs_generate_test_jump_expression(njs_vm_t *vm, njs_parser_t *parser,
     njs_parser_node_t *node)
 {
diff -r da89f264af94 -r f8cc880d9b9b njs/njs_parser_expression.c
--- a/njs/njs_parser_expression.c	Tue Oct 11 17:04:28 2016 +0300
+++ b/njs/njs_parser_expression.c	Tue Oct 11 17:44:01 2016 +0300
@@ -749,19 +749,31 @@ njs_parser_unary_expression(njs_vm_t *vm
         return next;
     }
 
-    if (token == NJS_TOKEN_TYPEOF
-        && parser->node->token == NJS_TOKEN_NAME)
-    {
-        parser->node->state = NJS_VARIABLE_TYPEOF;
+    if (token == NJS_TOKEN_DELETE) {
 
-    } else if (token == NJS_TOKEN_DELETE
-               && parser->node->token == NJS_TOKEN_PROPERTY)
-    {
-        parser->node->token = NJS_TOKEN_PROPERTY_DELETE;
-        parser->node->u.operation = njs_vmcode_property_delete;
-        parser->code_size += sizeof(njs_vmcode_3addr_t);
+        switch (parser->node->token) {
 
-        return next;
+        case NJS_TOKEN_PROPERTY:
+            parser->node->token = NJS_TOKEN_PROPERTY_DELETE;
+            parser->node->u.operation = njs_vmcode_property_delete;
+            parser->code_size += sizeof(njs_vmcode_3addr_t);
+
+            return next;
+
+        case NJS_TOKEN_NAME:
+        case NJS_TOKEN_UNDEFINED:
+            nxt_alert(&vm->trace, NXT_LEVEL_ERROR,
+                      "SyntaxError: Delete of an unqualified identifier");
+
+            return NJS_TOKEN_ILLEGAL;
+
+        default:
+            break;
+        }
+    }
+
+    if (token == NJS_TOKEN_TYPEOF && parser->node->token == NJS_TOKEN_NAME) {
+        parser->node->state = NJS_VARIABLE_TYPEOF;
     }
 
     node = njs_parser_node_alloc(vm);
diff -r da89f264af94 -r f8cc880d9b9b njs/njs_vm.c
--- a/njs/njs_vm.c	Tue Oct 11 17:04:28 2016 +0300
+++ b/njs/njs_vm.c	Tue Oct 11 17:44:01 2016 +0300
@@ -1466,8 +1466,6 @@ njs_vmcode_delete(njs_vm_t *vm, njs_valu
 {
     njs_release(vm, value);
 
-    njs_set_invalid(value);
-
     vm->retval = njs_value_true;
 
     return sizeof(njs_vmcode_2addr_t);
diff -r da89f264af94 -r f8cc880d9b9b njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Tue Oct 11 17:04:28 2016 +0300
+++ b/njs/test/njs_unit_test.c	Tue Oct 11 17:44:01 2016 +0300
@@ -1951,16 +1951,20 @@ static njs_unit_test_t  njs_test[] =
       nxt_string("true") },
 
     { nxt_string("var a; delete a"),
-      nxt_string("false") },
+      nxt_string("SyntaxError: Delete of an unqualified identifier in 1") },
 
     { nxt_string("delete undefined"),
-      nxt_string("false") },
+      nxt_string("SyntaxError: Delete of an unqualified identifier in 1") },
+
+    /* ES5FIX: "SyntaxError". */
 
     { nxt_string("delete NaN"),
-      nxt_string("false") },
+      nxt_string("true") },
+
+    /* ES5FIX: "SyntaxError". */
 
     { nxt_string("delete Infinity"),
-      nxt_string("false") },
+      nxt_string("true") },
 
     { nxt_string("delete -Infinity"),
       nxt_string("true") },
@@ -1971,21 +1975,24 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("delete 1"),
       nxt_string("true") },
 
-    { nxt_string("delete (a = 1); a"),
+    { nxt_string("var a; delete (a = 1); a"),
       nxt_string("1") },
 
     { nxt_string("delete a"),
-      nxt_string("true") },
+      nxt_string("SyntaxError: Delete of an unqualified identifier in 1") },
 
     { nxt_string("a = 1; delete a"),
-      nxt_string("true") },
-
-    { nxt_string("a = 1; delete a; typeof a"),
-      nxt_string("undefined") },
+      nxt_string("SyntaxError: Delete of an unqualified identifier in 1") },
+
+    { nxt_string("function f(){} delete f"),
+      nxt_string("SyntaxError: Delete of an unqualified identifier in 1") },
 
     { nxt_string("a = { x:1 }; ('x' in a) +' '+ (1 in a)"),
       nxt_string("true false") },
 
+    { nxt_string("delete --[][1]"),
+      nxt_string("true") },
+
     { nxt_string("a = {}; 1 in a"),
       nxt_string("false") },
 



More information about the nginx-devel mailing list