From f2ced3d91caf51504bcbcceabe35e1355a2cffc0 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Thu, 29 Oct 2015 15:00:39 +0300 Subject: [PATCH] Fix check for 'eval' and 'arguments' functions' names / argument names in strict mode. Related issue: #686 JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com --- jerry-core/parser/js/jsp-early-error.cpp | 35 ++++++++++++------------ jerry-core/parser/js/parser.cpp | 25 ++++++++++------- tests/jerry/regression-test-issue-686.js | 33 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 tests/jerry/regression-test-issue-686.js diff --git a/jerry-core/parser/js/jsp-early-error.cpp b/jerry-core/parser/js/jsp-early-error.cpp index 39433eed8..610ea44ec 100644 --- a/jerry-core/parser/js/jsp-early-error.cpp +++ b/jerry-core/parser/js/jsp-early-error.cpp @@ -207,46 +207,47 @@ void jsp_early_error_add_varg (jsp_operand_t op) } static void -emit_error_on_eval_and_arguments (jsp_operand_t op, locus loc __attr_unused___) +emit_error_on_eval_and_arguments (literal_t lit, locus loc __attr_unused___) { - if (op.is_literal_operand ()) + if (lit_literal_equal_type_utf8 (lit, + lit_get_magic_string_utf8 (LIT_MAGIC_STRING_ARGUMENTS), + lit_get_magic_string_size (LIT_MAGIC_STRING_ARGUMENTS)) + || lit_literal_equal_type_utf8 (lit, + lit_get_magic_string_utf8 (LIT_MAGIC_STRING_EVAL), + lit_get_magic_string_size (LIT_MAGIC_STRING_EVAL))) { - if (lit_literal_equal_type_utf8 (lit_get_literal_by_cp (op.get_literal ()), - lit_get_magic_string_utf8 (LIT_MAGIC_STRING_ARGUMENTS), - lit_get_magic_string_size (LIT_MAGIC_STRING_ARGUMENTS)) - || lit_literal_equal_type_utf8 (lit_get_literal_by_cp (op.get_literal ()), - lit_get_magic_string_utf8 (LIT_MAGIC_STRING_EVAL), - lit_get_magic_string_size (LIT_MAGIC_STRING_EVAL))) - { - PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "'eval' and 'arguments' are not allowed here in strict mode", loc); - } + PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "'eval' and 'arguments' are not allowed here in strict mode", loc); } } void jsp_early_error_check_for_eval_and_arguments_in_strict_mode (jsp_operand_t op, bool is_strict, locus loc) { - if (is_strict) + if (is_strict + && op.is_literal_operand ()) { - emit_error_on_eval_and_arguments (op, loc); + emit_error_on_eval_and_arguments (lit_get_literal_by_cp (op.get_literal ()), loc); } } /* 13.1, 15.3.2 */ void -jsp_early_error_check_for_syntax_errors_in_formal_param_list (bool is_strict, locus loc __attr_unused___) +jsp_early_error_check_for_syntax_errors_in_formal_param_list (bool is_strict, locus loc) { if (is_strict - && STACK_SIZE (props) - STACK_TOP (size_t_stack) >= 2) + && STACK_SIZE (props) - STACK_TOP (size_t_stack) >= 1) { - for (size_t i = (STACK_TOP (size_t_stack) + 1u); i < STACK_SIZE (props); i++) + for (size_t i = STACK_TOP (size_t_stack); i < STACK_SIZE (props); i++) { JERRY_ASSERT (STACK_ELEMENT (props, i).type == VARG); literal_t previous = STACK_ELEMENT (props, i).lit; JERRY_ASSERT (previous->get_type () == LIT_STR_T || previous->get_type () == LIT_MAGIC_STR_T || previous->get_type () == LIT_MAGIC_STR_EX_T); - for (size_t j = STACK_TOP (size_t_stack); j < i; j++) + + emit_error_on_eval_and_arguments (previous, loc); + + for (size_t j = i + 1; j < STACK_SIZE (props); j++) { JERRY_ASSERT (STACK_ELEMENT (props, j).type == VARG); literal_t current = STACK_ELEMENT (props, j).lit; diff --git a/jerry-core/parser/js/parser.cpp b/jerry-core/parser/js/parser.cpp index aa31bc0e6..2d08651ad 100644 --- a/jerry-core/parser/js/parser.cpp +++ b/jerry-core/parser/js/parser.cpp @@ -401,6 +401,8 @@ parse_property_assignment (void) scopes_tree_set_strict_mode (STACK_TOP (scopes), scopes_tree_strict_mode (STACK_HEAD (scopes, 2))); lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes))); + jsp_early_error_start_checking_of_vargs (); + skip_newlines (); const jsp_operand_t func = parse_argument_list (VARG_FUNC_EXPR, empty_operand (), NULL); @@ -425,6 +427,8 @@ parse_property_assignment (void) inside_function = was_in_function; + jsp_early_error_check_for_syntax_errors_in_formal_param_list (is_strict_mode (), tok.loc); + scopes_tree fe_scope_tree = STACK_TOP (scopes); STACK_DROP (scopes, 1); @@ -572,7 +576,6 @@ parse_argument_list (varg_list_type vlt, jsp_operand_t obj, jsp_operand_t *this_ current_token_must_be (TOK_NAME); op = literal_operand (token_data_as_lit_cp ()); jsp_early_error_add_varg (op); - jsp_early_error_check_for_eval_and_arguments_in_strict_mode (op, is_strict_mode (), tok.loc); dump_varg (op); skip_newlines (); } @@ -662,13 +665,6 @@ parse_function_declaration (void) jsp_label_t *masked_label_set_p = jsp_label_mask_set (); - token_after_newlines_must_be (TOK_NAME); - const jsp_operand_t name = literal_operand (token_data_as_lit_cp ()); - - jsp_early_error_check_for_eval_and_arguments_in_strict_mode (name, is_strict_mode (), tok.loc); - - skip_newlines (); - scopes_tree_set_contains_functions (STACK_TOP (scopes)); STACK_PUSH (scopes, scopes_tree_init (STACK_TOP (scopes), SCOPE_TYPE_FUNCTION)); @@ -676,6 +672,12 @@ parse_function_declaration (void) scopes_tree_set_strict_mode (STACK_TOP (scopes), scopes_tree_strict_mode (STACK_HEAD (scopes, 2))); lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes))); + token_after_newlines_must_be (TOK_NAME); + + const jsp_operand_t name = literal_operand (token_data_as_lit_cp ()); + + skip_newlines (); + jsp_early_error_start_checking_of_vargs (); parse_argument_list (VARG_FUNC_DECL, name, NULL); @@ -696,6 +698,7 @@ parse_function_declaration (void) inside_function = was_in_function; + jsp_early_error_check_for_eval_and_arguments_in_strict_mode (name, is_strict_mode (), tok.loc); jsp_early_error_check_for_syntax_errors_in_formal_param_list (is_strict_mode (), tok.loc); STACK_DROP (scopes, 1); @@ -728,10 +731,11 @@ parse_function_expression (void) lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes))); skip_newlines (); + + jsp_operand_t name = empty_operand (); if (token_is (TOK_NAME)) { - const jsp_operand_t name = literal_operand (token_data_as_lit_cp ()); - jsp_early_error_check_for_eval_and_arguments_in_strict_mode (name, is_strict_mode (), tok.loc); + name = literal_operand (token_data_as_lit_cp ()); skip_newlines (); res = parse_argument_list (VARG_FUNC_EXPR, name, NULL); @@ -765,6 +769,7 @@ parse_function_expression (void) inside_function = was_in_function; + jsp_early_error_check_for_eval_and_arguments_in_strict_mode (name, is_strict_mode (), tok.loc); jsp_early_error_check_for_syntax_errors_in_formal_param_list (is_strict_mode (), tok.loc); serializer_set_scope (STACK_HEAD (scopes, 2)); diff --git a/tests/jerry/regression-test-issue-686.js b/tests/jerry/regression-test-issue-686.js new file mode 100644 index 000000000..b89b70b60 --- /dev/null +++ b/tests/jerry/regression-test-issue-686.js @@ -0,0 +1,33 @@ +// Copyright 2015 Samsung Electronics Co., Ltd. +// Copyright 2015 University of Szeged. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +function check_syntax_error (code) { + try { + eval(code); + assert (false); + } catch (e) { + assert (e instanceof SyntaxError); + } +} + +check_syntax_error ("function eval () {'use strict';}"); +check_syntax_error ("function f (eval) {'use strict';}"); +check_syntax_error ("function arguments () {'use strict';}"); +check_syntax_error ("function f (arguments) {'use strict';}"); + +check_syntax_error ("(function eval () {'use strict';})"); +check_syntax_error ("(function f (eval) {'use strict';})"); +check_syntax_error ("(function arguments () {'use strict';})"); +check_syntax_error ("(function f (arguments) {'use strict';})");