From 26a299adf0318354caebf3294c46a35ddb9bae50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20B=C3=A1tyai?= Date: Fri, 31 Jul 2020 17:43:15 +0200 Subject: [PATCH] Fix block-scoped var/function redeclarations (#4080) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai daniel.batyai@h-lab.eu --- jerry-core/parser/js/js-scanner-util.c | 12 ++++++ jerry-core/parser/js/js-scanner.c | 8 ++++ tests/jerry/es.next/block-var-redecl.js | 56 +++++++++++++++++++++++++ tests/test262-es6-excludelist.xml | 4 +- tests/test262-esnext-excludelist.xml | 28 ------------- 5 files changed, 77 insertions(+), 31 deletions(-) create mode 100644 tests/jerry/es.next/block-var-redecl.js diff --git a/jerry-core/parser/js/js-scanner-util.c b/jerry-core/parser/js/js-scanner-util.c index b7130e787..01e992585 100644 --- a/jerry-core/parser/js/js-scanner-util.c +++ b/jerry-core/parser/js/js-scanner-util.c @@ -1382,6 +1382,14 @@ scanner_detect_invalid_var (parser_context_t *context_p, /**< context */ } scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p; + + if (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_BLOCK + && (var_literal_p->type & (SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION)) + == (SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION)) + { + scanner_raise_redeclaration_error (context_p); + } + const uint8_t *char_p = var_literal_p->char_p; prop_length_t length = var_literal_p->length; @@ -1399,6 +1407,8 @@ scanner_detect_invalid_var (parser_context_t *context_p, /**< context */ { if (literal_p->type & SCANNER_LITERAL_IS_LOCAL && !(literal_p->type & SCANNER_LITERAL_IS_ARG) + && !((literal_p->type & SCANNER_LITERAL_IS_FUNC) + && (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_BLOCK) == 0) && (literal_p->type & SCANNER_LITERAL_IS_LOCAL) != SCANNER_LITERAL_IS_LOCAL && literal_p->length == length) { @@ -1424,6 +1434,8 @@ scanner_detect_invalid_var (parser_context_t *context_p, /**< context */ { if (literal_p->type & SCANNER_LITERAL_IS_LOCAL && !(literal_p->type & SCANNER_LITERAL_IS_ARG) + && !((literal_p->type & SCANNER_LITERAL_IS_FUNC) + && (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_BLOCK) == 0) && (literal_p->type & SCANNER_LITERAL_IS_LOCAL) != SCANNER_LITERAL_IS_LOCAL && lexer_compare_identifiers (context_p, literal_p, var_literal_p)) { diff --git a/jerry-core/parser/js/js-scanner.c b/jerry-core/parser/js/js-scanner.c index 5beb12628..bd371933b 100644 --- a/jerry-core/parser/js/js-scanner.c +++ b/jerry-core/parser/js/js-scanner.c @@ -1438,6 +1438,14 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ scanner_raise_redeclaration_error (context_p); } + scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p; + + if (literal_pool_p->status_flags & SCANNER_LITERAL_POOL_BLOCK + && (literal_p->type & (SCANNER_LITERAL_IS_VAR))) + { + scanner_raise_redeclaration_error (context_p); + } + literal_p->type |= SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION; scanner_context_p->status_flags &= (uint16_t) ~SCANNER_CONTEXT_THROW_ERR_ASYNC_FUNCTION; diff --git a/tests/jerry/es.next/block-var-redecl.js b/tests/jerry/es.next/block-var-redecl.js new file mode 100644 index 000000000..af6c82351 --- /dev/null +++ b/tests/jerry/es.next/block-var-redecl.js @@ -0,0 +1,56 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// 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 (script) +{ + try + { + eval (script); + assert (false); + } + catch (e) + { + assert (e instanceof SyntaxError); + } +} + +eval("function f(){}; var f;"); +eval("var f; function f(){};"); + +eval("function f(){}; { var f; }") +eval("{ var f; } function f(){};") + +eval("{ function f(){}; } var f;") +eval("var f; { function f(){}; }") + +check_syntax_error ("{ function f(){}; var f; }"); +check_syntax_error ("{ var f; function f(){}; }"); + +eval("{ { function f(){}; } var f; }") +eval("{ var f; { function f(){}; } }") + +check_syntax_error ("{ function f(){}; { var f; } }") +check_syntax_error ("{ { var f; } function f(){}; }") + +eval("{ { function f(){}; } { var f; } }") +eval("{ { var f; } { function f(){}; } }") + +eval("function g(){ function f(){}; var f; }") +eval("function g(){ var f; function f(){}; }") + +eval("function g(){ function f(){}; { var f; } }") +eval("function g(){ { var f; } function f(){}; }") + +eval("function g(){ { function f(){}; } var f; }") +eval("function g(){ var f; { function f(){}; } }") diff --git a/tests/test262-es6-excludelist.xml b/tests/test262-es6-excludelist.xml index 85b025693..4cde487a4 100644 --- a/tests/test262-es6-excludelist.xml +++ b/tests/test262-es6-excludelist.xml @@ -253,9 +253,7 @@ - - - + No longer a SyntaxError in ES11 diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index 17c563e5f..f40b913e9 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -4099,38 +4099,18 @@ - - - - - - - - - - - - - - - - - - - - @@ -10417,26 +10397,18 @@ - - - - - - - -