From 720c3cc8cc66d294f48573a3103b9a5fc722d419 Mon Sep 17 00:00:00 2001 From: jugglinmike Date: Mon, 24 Oct 2016 13:43:44 -0400 Subject: [PATCH] Update for new `eval` restrictions on `super` (#781) A recent change to the specification [1] introduces parse-time errors for certain usages of `super` within eval code. Modify all tests that are affected by this change: - Update the test bodies to accurately enforce the new semantics - Rename files to better reflect the section of the specification that they enforce - Update test meta-data - Change the `esid` meta-data to reflect the location of the relevant specification text - Remove the `es6id` meta-data as the behavior is no longer relatable to that specification - Introduce the `features` meta-data in cases where the test file's new location no longer reflects all required language features [1] "Normative: Clarify rules around super inside eval" https://github.com/tc39/ecma262/pull/685 --- .../eval-code/direct/super-call-fn.js | 35 +++++++++---- .../eval-code/direct/super-call-method.js | 49 +++++++++++++++++++ .../direct/super-prop-dot-no-home.js | 47 ++++++++++++++++++ .../direct/super-prop-expr-no-home-no-eval.js | 46 +++++++++++++++++ .../direct/super-prop-expr-no-home.js | 47 ++++++++++++++++++ .../super/call-new-target-undef.js | 25 ---------- .../super/prop-dot-fn-no-super-bndng.js | 33 ------------- .../prop-expr-fn-eval-before-has-super.js | 24 --------- .../super/prop-expr-fn-no-super-bndng.js | 33 ------------- 9 files changed, 215 insertions(+), 124 deletions(-) create mode 100644 test/language/eval-code/direct/super-call-method.js create mode 100644 test/language/eval-code/direct/super-prop-dot-no-home.js create mode 100644 test/language/eval-code/direct/super-prop-expr-no-home-no-eval.js create mode 100644 test/language/eval-code/direct/super-prop-expr-no-home.js delete mode 100644 test/language/expressions/super/call-new-target-undef.js delete mode 100644 test/language/expressions/super/prop-dot-fn-no-super-bndng.js delete mode 100644 test/language/expressions/super/prop-expr-fn-eval-before-has-super.js delete mode 100644 test/language/expressions/super/prop-expr-fn-no-super-bndng.js diff --git a/test/language/eval-code/direct/super-call-fn.js b/test/language/eval-code/direct/super-call-fn.js index 542343d6c0..9dce93ae87 100644 --- a/test/language/eval-code/direct/super-call-fn.js +++ b/test/language/eval-code/direct/super-call-fn.js @@ -1,16 +1,33 @@ // Copyright (C) 2016 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -esid: sec-scripts-static-semantics-early-errors -es6id: 15.1.1 +esid: sec-performeval description: > - A direct eval in the functon code of a non-ArrowFunction may contain + A direct eval in the functon code of a non-ArrowFunction may not contain SuperCall info: | - - It is a Syntax Error if StatementList Contains super unless the source code - containing super is eval code that is being processed by a direct eval that - is contained in function code that is not the function code of an - ArrowFunction. + [...] + 4. Let inMethod be false. + 5. Let inConstructor be false. + 6. If thisEnvRec has a [[HomeObject]] field, then + a. Let inMethod be true. + b. If thisEnvRec.[[FunctionObject]] has a [[Construct]] field, let + inConstructor be true. + 7. Let script be the ECMAScript code that is the result of parsing x, + interpreted as UTF-16 encoded Unicode text as described in 6.1.4, for the + goal symbol Script. If inMethod is false, additional early error rules + from 18.2.1.1.1 are applied. If inConstructor is false, additional early + error rules from 18.2.1.1.2 are applied. If the parse fails, throw a + SyntaxError exception. If any early errors are detected, throw a + SyntaxError or a ReferenceError exception, depending on the type of the + error (but see also clause 16). Parsing and early error detection may be + interweaved in an implementation dependent manner. + + 18.2.1.1.1 Additional Early Error Rules for Eval Outside Methods + + ScriptBody : StatementList + + - It is a Syntax Error if StatementList contains super. features: [super] ---*/ @@ -19,8 +36,8 @@ function f() { eval('executed = true; super();'); } -assert.throws(ReferenceError, function() { +assert.throws(SyntaxError, function() { f(); }); -assert.sameValue(executed, true); +assert.sameValue(executed, false); diff --git a/test/language/eval-code/direct/super-call-method.js b/test/language/eval-code/direct/super-call-method.js new file mode 100644 index 0000000000..a154b0704a --- /dev/null +++ b/test/language/eval-code/direct/super-call-method.js @@ -0,0 +1,49 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-performeval +description: > + SuperCall may may only occur in eval code for direct eval within a + constructor method +info: | + [...] + 4. Let inMethod be false. + 5. Let inConstructor be false. + 6. If thisEnvRec has a [[HomeObject]] field, then + a. Let inMethod be true. + b. If thisEnvRec.[[FunctionObject]] has a [[Construct]] field, let + inConstructor be true. + 7. Let script be the ECMAScript code that is the result of parsing x, + interpreted as UTF-16 encoded Unicode text as described in 6.1.4, for the + goal symbol Script. If inMethod is false, additional early error rules + from 18.2.1.1.1 are applied. If inConstructor is false, additional early + error rules from 18.2.1.1.2 are applied. If the parse fails, throw a + SyntaxError exception. If any early errors are detected, throw a + SyntaxError or a ReferenceError exception, depending on the type of the + error (but see also clause 16). Parsing and early error detection may be + interweaved in an implementation dependent manner. + + 18.2.1.1.1 Additional Early Error Rules for Eval Outside Methods + + ScriptBody : StatementList + + - It is a Syntax Error if StatementList contains super. +features: [super] +---*/ + +var evaluatedArg = false; +var obj = { + method() { + // Early errors restricting the usage of SuperCall necessitate the use of + // `eval`. + eval('super(evaluatedArg = true);'); + } +} + +assert.throws(SyntaxError, function() { + obj.method(); +}); + +assert.sameValue( + evaluatedArg, false, 'did not perform ArgumentsListEvaluation' +); diff --git a/test/language/eval-code/direct/super-prop-dot-no-home.js b/test/language/eval-code/direct/super-prop-dot-no-home.js new file mode 100644 index 0000000000..9b18104bb6 --- /dev/null +++ b/test/language/eval-code/direct/super-prop-dot-no-home.js @@ -0,0 +1,47 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-performeval +description: > + SuperProperty may may only occur in eval code for direct eval within a method +info: | + [...] + 4. Let inMethod be false. + 5. Let inConstructor be false. + 6. If thisEnvRec has a [[HomeObject]] field, then + a. Let inMethod be true. + b. If thisEnvRec.[[FunctionObject]] has a [[Construct]] field, let + inConstructor be true. + 7. Let script be the ECMAScript code that is the result of parsing x, + interpreted as UTF-16 encoded Unicode text as described in 6.1.4, for the + goal symbol Script. If inMethod is false, additional early error rules + from 18.2.1.1.1 are applied. If inConstructor is false, additional early + error rules from 18.2.1.1.2 are applied. If the parse fails, throw a + SyntaxError exception. If any early errors are detected, throw a + SyntaxError or a ReferenceError exception, depending on the type of the + error (but see also clause 16). Parsing and early error detection may be + interweaved in an implementation dependent manner. + + 18.2.1.1.1 Additional Early Error Rules for Eval Outside Methods + + ScriptBody : StatementList + + - It is a Syntax Error if StatementList contains super. +features: [super] +---*/ + +var caught; +function f() { + // Early errors restricting the usage of SuperProperty necessitate the use of + // `eval`. + try { + eval('super.x;'); + } catch (err) { + caught = err; + } +} + +f(); + +assert.sameValue(typeof caught, 'object'); +assert.sameValue(caught.constructor, SyntaxError); diff --git a/test/language/eval-code/direct/super-prop-expr-no-home-no-eval.js b/test/language/eval-code/direct/super-prop-expr-no-home-no-eval.js new file mode 100644 index 0000000000..db40dbad2e --- /dev/null +++ b/test/language/eval-code/direct/super-prop-expr-no-home-no-eval.js @@ -0,0 +1,46 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-performeval +description: > + Expression is not evaluated prior to verification of "super" binding +info: | + [...] + 4. Let inMethod be false. + 5. Let inConstructor be false. + 6. If thisEnvRec has a [[HomeObject]] field, then + a. Let inMethod be true. + b. If thisEnvRec.[[FunctionObject]] has a [[Construct]] field, let + inConstructor be true. + 7. Let script be the ECMAScript code that is the result of parsing x, + interpreted as UTF-16 encoded Unicode text as described in 6.1.4, for the + goal symbol Script. If inMethod is false, additional early error rules + from 18.2.1.1.1 are applied. If inConstructor is false, additional early + error rules from 18.2.1.1.2 are applied. If the parse fails, throw a + SyntaxError exception. If any early errors are detected, throw a + SyntaxError or a ReferenceError exception, depending on the type of the + error (but see also clause 16). Parsing and early error detection may be + interweaved in an implementation dependent manner. + + 18.2.1.1.1 Additional Early Error Rules for Eval Outside Methods + + ScriptBody : StatementList + + - It is a Syntax Error if StatementList contains super. +features: [super] +---*/ + +var evaluated = false; +function f() { + // Early errors restricting the usage of SuperProperty necessitate the use of + // `eval`. + try { + eval('super[evaluated = true];'); + // Evaluation of SuperProperty is expected to fail in this context, but that + // behavior is tested elsewhere, so the error is discarded. + } catch (_) {} +} + +f(); + +assert.sameValue(evaluated, false); diff --git a/test/language/eval-code/direct/super-prop-expr-no-home.js b/test/language/eval-code/direct/super-prop-expr-no-home.js new file mode 100644 index 0000000000..ad23aa08ed --- /dev/null +++ b/test/language/eval-code/direct/super-prop-expr-no-home.js @@ -0,0 +1,47 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-performeval +description: > + SuperProperty may may only occur in eval code for direct eval within a method +info: | + [...] + 4. Let inMethod be false. + 5. Let inConstructor be false. + 6. If thisEnvRec has a [[HomeObject]] field, then + a. Let inMethod be true. + b. If thisEnvRec.[[FunctionObject]] has a [[Construct]] field, let + inConstructor be true. + 7. Let script be the ECMAScript code that is the result of parsing x, + interpreted as UTF-16 encoded Unicode text as described in 6.1.4, for the + goal symbol Script. If inMethod is false, additional early error rules + from 18.2.1.1.1 are applied. If inConstructor is false, additional early + error rules from 18.2.1.1.2 are applied. If the parse fails, throw a + SyntaxError exception. If any early errors are detected, throw a + SyntaxError or a ReferenceError exception, depending on the type of the + error (but see also clause 16). Parsing and early error detection may be + interweaved in an implementation dependent manner. + + 18.2.1.1.1 Additional Early Error Rules for Eval Outside Methods + + ScriptBody : StatementList + + - It is a Syntax Error if StatementList contains super. +features: [super] +---*/ + +var caught; +function f() { + // Early errors restricting the usage of SuperProperty necessitate the use of + // `eval`. + try { + eval('super["x"];'); + } catch (err) { + caught = err; + } +} + +f(); + +assert.sameValue(typeof caught, 'object'); +assert.sameValue(caught.constructor, SyntaxError); diff --git a/test/language/expressions/super/call-new-target-undef.js b/test/language/expressions/super/call-new-target-undef.js deleted file mode 100644 index 61994045a4..0000000000 --- a/test/language/expressions/super/call-new-target-undef.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2016 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-super-keyword -es6id: 12.3.5 -description: SuperCall requires that NewTarget is defined -info: | - 1. Let newTarget be GetNewTarget(). - 2. If newTarget is undefined, throw a ReferenceError exception. ----*/ - -var evaluatedArg = false; -function f() { - // Early errors restricting the usage of SuperCall necessitate the use of - // `eval`. - eval('super(evaluatedArg = true);'); -} - -assert.throws(ReferenceError, function() { - f(); -}); - -assert.sameValue( - evaluatedArg, false, 'did not perform ArgumentsListEvaluation' -); diff --git a/test/language/expressions/super/prop-dot-fn-no-super-bndng.js b/test/language/expressions/super/prop-dot-fn-no-super-bndng.js deleted file mode 100644 index e376ce149b..0000000000 --- a/test/language/expressions/super/prop-dot-fn-no-super-bndng.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2016 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-super-keyword -es6id: 12.3.5 -description: ReferenceError is thrown when environment has no "super" binding -info: | - 1. Let propertyKey be StringValue of IdentifierName. - 2. If the code matched by the syntactic production that is being evaluated is - strict mode code, let strict be true, else let strict be false. - 3. Return ? MakeSuperPropertyReference(propertyKey, strict). - - 12.3.5.3 Runtime Semantics: MakeSuperPropertyReference - - 1. Let env be GetThisEnvironment( ). - 2. If env.HasSuperBinding() is false, throw a ReferenceError exception. ----*/ - -var caught; -function f() { - // Early errors restricting the usage of SuperProperty necessitate the use of - // `eval`. - try { - eval('super.x;'); - } catch (err) { - caught = err; - } -} - -f(); - -assert.sameValue(typeof caught, 'object'); -assert.sameValue(caught.constructor, ReferenceError); diff --git a/test/language/expressions/super/prop-expr-fn-eval-before-has-super.js b/test/language/expressions/super/prop-expr-fn-eval-before-has-super.js deleted file mode 100644 index df93e61602..0000000000 --- a/test/language/expressions/super/prop-expr-fn-eval-before-has-super.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2016 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-super-keyword -es6id: 12.3.5 -description: Expression is evaluated prior to verification of "super" binding -info: | - 1. Let propertyNameReference be the result of evaluating Expression. ----*/ - -var evaluated = false; -function f() { - // Early errors restricting the usage of SuperProperty necessitate the use of - // `eval`. - try { - eval('super[evaluated = true];'); - // Evaluation of SuperProperty is expected to fail in this context, but that - // behavior is tested elsewhere, so the error is discarded. - } catch (_) {} -} - -f(); - -assert.sameValue(evaluated, true); diff --git a/test/language/expressions/super/prop-expr-fn-no-super-bndng.js b/test/language/expressions/super/prop-expr-fn-no-super-bndng.js deleted file mode 100644 index d56cd27b5c..0000000000 --- a/test/language/expressions/super/prop-expr-fn-no-super-bndng.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2016 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-super-keyword -es6id: 12.3.5 -description: ReferenceError is thrown when environment has no "super" binding -info: | - [...] - 4. If the code matched by the syntactic production that is being evaluated is - strict mode code, let strict be true, else let strict be false. - 5. Return ? MakeSuperPropertyReference(propertyKey, strict). - - 12.3.5.3 Runtime Semantics: MakeSuperPropertyReference - - 1. Let env be GetThisEnvironment( ). - 2. If env.HasSuperBinding() is false, throw a ReferenceError exception. ----*/ - -var caught; -function f() { - // Early errors restricting the usage of SuperProperty necessitate the use of - // `eval`. - try { - eval('super["x"];'); - } catch (err) { - caught = err; - } -} - -f(); - -assert.sameValue(typeof caught, 'object'); -assert.sameValue(caught.constructor, ReferenceError);