From 663a9eeae401f8d915b3f39d6c184519d46a1fd7 Mon Sep 17 00:00:00 2001 From: caitpotter88 Date: Mon, 16 Feb 2015 10:18:05 -0800 Subject: [PATCH] [parsing]: eval/arguments parameter names are ok in sloppy mode BUG=v8:3891 LOG=N R=arv@chromium.org, marja@chromium.org Review URL: https://codereview.chromium.org/924403002 Cr-Commit-Position: refs/heads/master@{#26673} --- src/parser.cc | 3 +- src/preparser.h | 2 +- src/scopes.h | 7 +++ test/cctest/test-parsing.cc | 140 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 148 insertions(+), 4 deletions(-) diff --git a/src/parser.cc b/src/parser.cc index 2e2eea7..08941f5 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -3702,7 +3702,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral( if (!reserved_error_loc.IsValid() && is_strict_reserved) { reserved_error_loc = scanner()->location(); } - if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { + if (!dupe_error_loc.IsValid() && + scope_->IsDeclaredParameter(param_name)) { duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; dupe_error_loc = scanner()->location(); } diff --git a/src/preparser.h b/src/preparser.h index c11bbd1..9f8fc13 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -475,7 +475,7 @@ class ParserBase : public Traits { bool* ok) { if (is_sloppy(language_mode) && !strict_params) return; - if (eval_args_error_loc.IsValid()) { + if (is_strict(language_mode) && eval_args_error_loc.IsValid()) { Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); *ok = false; return; diff --git a/src/scopes.h b/src/scopes.h index 56a7ee9..c3f4f8e 100644 --- a/src/scopes.h +++ b/src/scopes.h @@ -467,6 +467,13 @@ class Scope: public ZoneObject { return variables_.Lookup(name) != NULL; } + bool IsDeclaredParameter(const AstRawString* name) { + // If IsSimpleParameterList is false, duplicate parameters are not allowed, + // however `arguments` may be allowed if function is not strict code. Thus, + // the assumptions explained above do not hold. + return params_.Contains(variables_.Lookup(name)); + } + // --------------------------------------------------------------------------- // Debugging. diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index 2ee81cf..7a624cb 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -3965,8 +3965,6 @@ TEST(MethodDefinitionStrictFormalParamereters) { const char* params_data[] = { "x, x", "x, y, x", - "eval", - "arguments", "var", "const", NULL @@ -3978,6 +3976,57 @@ TEST(MethodDefinitionStrictFormalParamereters) { } +TEST(MethodDefinitionEvalArguments) { + const char* strict_context_data[][2] = + {{"'use strict'; ({method(", "){}});"}, + {"'use strict'; ({*method(", "){}});"}, + {NULL, NULL}}; + const char* sloppy_context_data[][2] = + {{"({method(", "){}});"}, + {"({*method(", "){}});"}, + {NULL, NULL}}; + + const char* data[] = { + "eval", + "arguments", + NULL}; + + static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals}; + + // Fail in strict mode + RunParserSyncTest(strict_context_data, data, kError, NULL, 0, always_flags, + arraysize(always_flags)); + + // OK in sloppy mode + RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, always_flags, + arraysize(always_flags)); +} + + +TEST(MethodDefinitionDuplicateEvalArguments) { + const char* context_data[][2] = + {{"'use strict'; ({method(", "){}});"}, + {"'use strict'; ({*method(", "){}});"}, + {"({method(", "){}});"}, + {"({*method(", "){}});"}, + {NULL, NULL}}; + + const char* data[] = { + "eval, eval", + "eval, a, eval", + "arguments, arguments", + "arguments, a, arguments", + NULL}; + + static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals}; + + // In strict mode, the error is using "eval" or "arguments" as parameter names + // In sloppy mode, the error is that eval / arguments are duplicated + RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, + arraysize(always_flags)); +} + + TEST(MethodDefinitionDuplicateProperty) { const char* context_data[][2] = {{"'use strict'; ({", "});"}, {NULL, NULL}}; @@ -4880,6 +4929,59 @@ TEST(ParseRestParametersErrors) { } +TEST(RestParametersEvalArguments) { + const char* strict_context_data[][2] = + {{"'use strict';(function(", + "){ return;})(1, [], /regexp/, 'str',function(){});"}, + {NULL, NULL}}; + const char* sloppy_context_data[][2] = + {{"(function(", + "){ return;})(1, [],/regexp/, 'str', function(){});"}, + {NULL, NULL}}; + + const char* data[] = { + "...eval", + "eval, ...args", + "...arguments", + "arguments, ...args", + NULL}; + + static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters}; + + // Fail in strict mode + RunParserSyncTest(strict_context_data, data, kError, NULL, 0, always_flags, + arraysize(always_flags)); + + // OK in sloppy mode + RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, always_flags, + arraysize(always_flags)); +} + + +TEST(RestParametersDuplicateEvalArguments) { + const char* context_data[][2] = + {{"'use strict';(function(", + "){ return;})(1, [], /regexp/, 'str',function(){});"}, + {"(function(", + "){ return;})(1, [],/regexp/, 'str', function(){});"}, + {NULL, NULL}}; + + const char* data[] = { + "eval, ...eval", + "eval, eval, ...args", + "arguments, ...arguments", + "arguments, arguments, ...args", + NULL}; + + static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters}; + + // In strict mode, the error is using "eval" or "arguments" as parameter names + // In sloppy mode, the error is that eval / arguments are duplicated + RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, + arraysize(always_flags)); +} + + TEST(LexicalScopingSloppyMode) { const char* context_data[][2] = { {"", ""}, @@ -5317,3 +5419,37 @@ TEST(PropertyNameEvalArguments) { RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); } + + +TEST(FunctionLiteralDuplicateParameters) { + const char* strict_context_data[][2] = + {{"'use strict';(function(", "){})();"}, + {"(function(", ") { 'use strict'; })();"}, + {"'use strict'; function fn(", ") {}; fn();"}, + {"function fn(", ") { 'use strict'; }; fn();"}, + {"'use strong';(function(", "){})();"}, + {"(function(", ") { 'use strong'; })();"}, + {"'use strong'; function fn(", ") {}; fn();"}, + {"function fn(", ") { 'use strong'; }; fn();"}, + {NULL, NULL}}; + + const char* sloppy_context_data[][2] = + {{"(function(", "){})();"}, + {"(function(", ") {})();"}, + {"function fn(", ") {}; fn();"}, + {"function fn(", ") {}; fn();"}, + {NULL, NULL}}; + + const char* data[] = { + "a, a", + "a, a, a", + "b, a, a", + "a, b, c, c", + "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, w", + NULL}; + + static const ParserFlag always_flags[] = { kAllowStrongMode }; + RunParserSyncTest(strict_context_data, data, kError, NULL, 0, always_flags, + arraysize(always_flags)); + RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, NULL, 0); +} -- 2.7.4