* Allow duplicate __proto__ keys in patterns, simple case (#6705) * Update test262 whitelist * Rename checkDuplicatedProto's parameter and adjust type * Store first __proto__ redefinition's position
This commit is contained in:
parent
dcf7d89b8e
commit
06313a6288
@ -67,14 +67,13 @@ export default class ExpressionParser extends LValParser {
|
|||||||
+parseFunctionParams: (node: N.Function, allowModifiers?: boolean) => void;
|
+parseFunctionParams: (node: N.Function, allowModifiers?: boolean) => void;
|
||||||
+takeDecorators: (node: N.HasDecorators) => void;
|
+takeDecorators: (node: N.HasDecorators) => void;
|
||||||
|
|
||||||
// Check if property name clashes with already added.
|
// Check if property __proto__ has been used more than once.
|
||||||
// Object/class getters and setters are not allowed to clash —
|
// If the expression is a destructuring assignment, then __proto__ may appear
|
||||||
// either with each other or with an init property — and in
|
// multiple times. Otherwise, __proto__ is a duplicated key.
|
||||||
// strict mode, init properties are also not allowed to be repeated.
|
|
||||||
|
|
||||||
checkPropClash(
|
checkDuplicatedProto(
|
||||||
prop: N.ObjectMember | N.SpreadElement,
|
prop: N.ObjectMember | N.SpreadElement,
|
||||||
propHash: { [key: string]: boolean },
|
protoRef: { used: boolean, start?: number },
|
||||||
): void {
|
): void {
|
||||||
if (
|
if (
|
||||||
prop.type === "SpreadElement" ||
|
prop.type === "SpreadElement" ||
|
||||||
@ -91,10 +90,12 @@ export default class ExpressionParser extends LValParser {
|
|||||||
const name = key.type === "Identifier" ? key.name : String(key.value);
|
const name = key.type === "Identifier" ? key.name : String(key.value);
|
||||||
|
|
||||||
if (name === "__proto__") {
|
if (name === "__proto__") {
|
||||||
if (propHash.proto) {
|
// Store the first redefinition's position
|
||||||
this.raise(key.start, "Redefinition of __proto__ property");
|
if (protoRef.used && !protoRef.start) {
|
||||||
|
protoRef.start = key.start;
|
||||||
}
|
}
|
||||||
propHash.proto = true;
|
|
||||||
|
protoRef.used = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1515,7 +1516,7 @@ export default class ExpressionParser extends LValParser {
|
|||||||
|
|
||||||
const prop = this.parseObjectMember(isPattern, refShorthandDefaultPos);
|
const prop = this.parseObjectMember(isPattern, refShorthandDefaultPos);
|
||||||
// $FlowIgnore RestElement will never be returned if !isPattern
|
// $FlowIgnore RestElement will never be returned if !isPattern
|
||||||
if (!isPattern) this.checkPropClash(prop, propHash);
|
if (!isPattern) this.checkDuplicatedProto(prop, propHash);
|
||||||
|
|
||||||
// $FlowIgnore
|
// $FlowIgnore
|
||||||
if (prop.shorthand) {
|
if (prop.shorthand) {
|
||||||
@ -1525,6 +1526,10 @@ export default class ExpressionParser extends LValParser {
|
|||||||
node.properties.push(prop);
|
node.properties.push(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.match(tt.eq) && propHash.start !== undefined) {
|
||||||
|
this.raise(propHash.start, "Redefinition of __proto__ property");
|
||||||
|
}
|
||||||
|
|
||||||
return this.finishNode(
|
return this.finishNode(
|
||||||
node,
|
node,
|
||||||
isPattern ? "ObjectPattern" : "ObjectExpression",
|
isPattern ? "ObjectPattern" : "ObjectExpression",
|
||||||
|
|||||||
@ -125,9 +125,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPropClash(
|
checkDuplicatedProto(
|
||||||
prop: N.ObjectMember | N.SpreadElement,
|
prop: N.ObjectMember | N.SpreadElement,
|
||||||
propHash: { [key: string]: boolean },
|
protoRef: { used: boolean, start?: number },
|
||||||
): void {
|
): void {
|
||||||
if (
|
if (
|
||||||
prop.type === "SpreadElement" ||
|
prop.type === "SpreadElement" ||
|
||||||
@ -144,10 +144,12 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
const name = key.type === "Identifier" ? key.name : String(key.value);
|
const name = key.type === "Identifier" ? key.name : String(key.value);
|
||||||
|
|
||||||
if (name === "__proto__" && prop.kind === "init") {
|
if (name === "__proto__" && prop.kind === "init") {
|
||||||
if (propHash.proto) {
|
// Store the first redefinition's position
|
||||||
this.raise(key.start, "Redefinition of __proto__ property");
|
if (protoRef.used && !protoRef.start) {
|
||||||
|
protoRef.start = key.start;
|
||||||
}
|
}
|
||||||
propHash.proto = true;
|
|
||||||
|
protoRef.used = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
packages/babel-parser/test/fixtures/es2015/destructuring/duplicate-proto/input.js
vendored
Normal file
1
packages/babel-parser/test/fixtures/es2015/destructuring/duplicate-proto/input.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
({ __proto__: x, __proto__: y } = {});
|
||||||
207
packages/babel-parser/test/fixtures/es2015/destructuring/duplicate-proto/output.json
vendored
Normal file
207
packages/babel-parser/test/fixtures/es2015/destructuring/duplicate-proto/output.json
vendored
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
{
|
||||||
|
"type": "File",
|
||||||
|
"start": 0,
|
||||||
|
"end": 38,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 38
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"type": "Program",
|
||||||
|
"start": 0,
|
||||||
|
"end": 38,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 38
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceType": "script",
|
||||||
|
"interpreter": null,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "ExpressionStatement",
|
||||||
|
"start": 0,
|
||||||
|
"end": 38,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 38
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"expression": {
|
||||||
|
"type": "AssignmentExpression",
|
||||||
|
"start": 1,
|
||||||
|
"end": 36,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 1
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 36
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"operator": "=",
|
||||||
|
"left": {
|
||||||
|
"type": "ObjectPattern",
|
||||||
|
"start": 1,
|
||||||
|
"end": 31,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 1
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 31
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"type": "ObjectProperty",
|
||||||
|
"start": 3,
|
||||||
|
"end": 15,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 3
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"method": false,
|
||||||
|
"key": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 3,
|
||||||
|
"end": 12,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 3
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 12
|
||||||
|
},
|
||||||
|
"identifierName": "__proto__"
|
||||||
|
},
|
||||||
|
"name": "__proto__"
|
||||||
|
},
|
||||||
|
"computed": false,
|
||||||
|
"shorthand": false,
|
||||||
|
"value": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 14,
|
||||||
|
"end": 15,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 14
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 15
|
||||||
|
},
|
||||||
|
"identifierName": "x"
|
||||||
|
},
|
||||||
|
"name": "x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ObjectProperty",
|
||||||
|
"start": 17,
|
||||||
|
"end": 29,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 17
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 29
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"method": false,
|
||||||
|
"key": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 17,
|
||||||
|
"end": 26,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 17
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 26
|
||||||
|
},
|
||||||
|
"identifierName": "__proto__"
|
||||||
|
},
|
||||||
|
"name": "__proto__"
|
||||||
|
},
|
||||||
|
"computed": false,
|
||||||
|
"shorthand": false,
|
||||||
|
"value": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 28,
|
||||||
|
"end": 29,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 28
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 29
|
||||||
|
},
|
||||||
|
"identifierName": "y"
|
||||||
|
},
|
||||||
|
"name": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"type": "ObjectExpression",
|
||||||
|
"start": 34,
|
||||||
|
"end": 36,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 34
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 36
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": []
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"parenthesized": true,
|
||||||
|
"parenStart": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": []
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,3 @@
|
|||||||
language/expressions/assignment/destructuring/obj-prop-__proto__dup.js(default)
|
|
||||||
language/expressions/assignment/destructuring/obj-prop-__proto__dup.js(strict mode)
|
|
||||||
language/expressions/class/elements/fields-duplicate-privatenames.js(default)
|
language/expressions/class/elements/fields-duplicate-privatenames.js(default)
|
||||||
language/expressions/class/elements/fields-duplicate-privatenames.js(strict mode)
|
language/expressions/class/elements/fields-duplicate-privatenames.js(strict mode)
|
||||||
language/expressions/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage-chained-usage.js(default)
|
language/expressions/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage-chained-usage.js(default)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user