From: Igor Sysoev Date: Tue, 11 Oct 2016 14:44:01 +0000 (+0300) Subject: Segfaults in the delete operator have been fixed. X-Git-Tag: 0.1.4~19 X-Git-Url: http://git.kaiwu.me/%7B@url%7D?a=commitdiff_plain;h=4ad1a32cefa3fb63431b2abf50eca24035937518;p=njs.git Segfaults in the delete operator have been fixed. --- diff --git a/njs/njs_generator.c b/njs/njs_generator.c index a262638e..071ce3bd 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -21,7 +21,6 @@ #include #include #include -#include 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(njs_vm_t *vm, njs_parser_t *parser, 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 *parser, njs_parser_node_t *node) 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: @@ -1577,78 +1572,6 @@ 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) -{ - 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 --git a/njs/njs_parser_expression.c b/njs/njs_parser_expression.c index 6464dd6e..6de22910 100644 --- a/njs/njs_parser_expression.c +++ b/njs/njs_parser_expression.c @@ -749,19 +749,31 @@ njs_parser_unary_expression(njs_vm_t *vm, njs_parser_t *parser, 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 --git a/njs/njs_vm.c b/njs/njs_vm.c index e8b15074..18051974 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -1466,8 +1466,6 @@ njs_vmcode_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld) { njs_release(vm, value); - njs_set_invalid(value); - vm->retval = njs_value_true; return sizeof(njs_vmcode_2addr_t); diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index f1e9fa86..5d9d6447 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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("SyntaxError: Delete of an unqualified identifier in 1") }, - { nxt_string("a = 1; delete a; typeof a"), - nxt_string("undefined") }, + { 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") },