Fix #4787: Destructuring of objects within arrays can generate invalid JavaScript (#4791)

* Fix #4787

* simplify condition
This commit is contained in:
zdenko 2017-11-21 05:00:27 +01:00 committed by Geoffrey Booth
parent 555c22af58
commit 9812d28748
3 changed files with 13 additions and 2 deletions

View File

@ -3286,7 +3286,9 @@
answer = compiledName.concat(this.makeCode(` ${this.context || '='} `), val);
// Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration,
// if were destructuring without declaring, the destructuring assignment must be wrapped in parentheses.
if (o.level > LEVEL_LIST || o.level === LEVEL_TOP && isValue && this.variable.base instanceof Obj && !this.nestedLhs && !(this.param === true)) {
// The assignment is wrapped in parentheses if 'o.level' has lower precedence than LEVEL_LIST (3)
// (i.e. LEVEL_COND (4), LEVEL_OP (5) or LEVEL_ACCESS (6)), or if we're destructuring object, e.g. {a,b} = obj.
if (o.level > LEVEL_LIST || isValue && this.variable.base instanceof Obj && !this.nestedLhs && !(this.param === true)) {
return this.wrapInParentheses(answer);
} else {
return answer;

View File

@ -2209,7 +2209,9 @@ exports.Assign = class Assign extends Base
answer = compiledName.concat @makeCode(" #{ @context or '=' } "), val
# Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration,
# if were destructuring without declaring, the destructuring assignment must be wrapped in parentheses.
if o.level > LEVEL_LIST or o.level is LEVEL_TOP and isValue and @variable.base instanceof Obj and not @nestedLhs and not (@param is yes)
# The assignment is wrapped in parentheses if 'o.level' has lower precedence than LEVEL_LIST (3)
# (i.e. LEVEL_COND (4), LEVEL_OP (5) or LEVEL_ACCESS (6)), or if we're destructuring object, e.g. {a,b} = obj.
if o.level > LEVEL_LIST or isValue and @variable.base instanceof Obj and not @nestedLhs and not (@param is yes)
@wrapInParentheses answer
else
answer

View File

@ -178,6 +178,13 @@ test "#713: destructuring assignment should return right-hand-side value", ->
eq nonceB, b
eq nonceB, d
test "#4787 destructuring of objects within arrays", ->
arr = [1, {a:1, b:2}]
[...,{a, b}] = arr
eq a, 1
eq b, arr[1].b
deepEqual {a, b}, arr[1]
test "destructuring assignment with splats", ->
a = {}; b = {}; c = {}; d = {}; e = {}
[x,y...,z] = [a,b,c,d,e]