[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