From 5d91a42b06420da16cb9bc1a7e2a37a012230053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Sun, 31 May 2020 17:54:56 -0400 Subject: [PATCH] fix: disallow __proto__ in record --- packages/babel-parser/src/parser/error-message.js | 1 + packages/babel-parser/src/parser/expression.js | 15 +++++++++++---- packages/babel-parser/src/plugins/estree.js | 5 +++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/babel-parser/src/parser/error-message.js b/packages/babel-parser/src/parser/error-message.js index 0737323af392..363873efb5ec 100644 --- a/packages/babel-parser/src/parser/error-message.js +++ b/packages/babel-parser/src/parser/error-message.js @@ -126,6 +126,7 @@ export const ErrorMessages = Object.freeze({ "Record expressions starting with '{|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'", RecordExpressionHashIncorrectStartSyntaxType: "Record expressions starting with '#{' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'", + RecordNoProto: "'__proto__' is not allowed in Record expressions", RestTrailingComma: "Unexpected trailing comma after rest element", SloppyFunction: "In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement", diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index cee5d30bc0d2..1551a0cad007 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -74,12 +74,15 @@ export default class ExpressionParser extends LValParser { +takeDecorators: (node: N.HasDecorators) => void; */ - // Check if property __proto__ has been used more than once. + // For object literal, check if property __proto__ has been used more than once. // If the expression is a destructuring assignment, then __proto__ may appear // multiple times. Otherwise, __proto__ is a duplicated key. - checkDuplicatedProto( + // For record expression, check if property __proto__ exists but allows "__proto__" + + checkProto( prop: N.ObjectMember | N.SpreadElement, + isRecord: boolean, protoRef: { used: boolean }, refExpressionErrors: ?ExpressionErrors, ): void { @@ -95,9 +98,13 @@ export default class ExpressionParser extends LValParser { const key = prop.key; // It is either an Identifier or a String/NumericLiteral - const name = key.type === "Identifier" ? key.name : String(key.value); + const name = key.type === "Identifier" ? key.name : key.value; if (name === "__proto__") { + if (isRecord) { + this.raise(key.start, Errors.RecordNoProto); + return; + } if (protoRef.used) { if (refExpressionErrors) { // Store the first redefinition's position, otherwise ignore because @@ -1554,7 +1561,7 @@ export default class ExpressionParser extends LValParser { const prop = this.parseObjectMember(isPattern, refExpressionErrors); if (!isPattern) { // $FlowIgnore RestElement will never be returned if !isPattern - this.checkDuplicatedProto(prop, propHash, refExpressionErrors); + this.checkProto(prop, isRecord, propHash, refExpressionErrors); } if ( diff --git a/packages/babel-parser/src/plugins/estree.js b/packages/babel-parser/src/plugins/estree.js index f8021751dfcd..796e0d7e5293 100644 --- a/packages/babel-parser/src/plugins/estree.js +++ b/packages/babel-parser/src/plugins/estree.js @@ -143,8 +143,9 @@ export default (superClass: Class): Class => } } - checkDuplicatedProto( + checkProto( prop: N.ObjectMember | N.SpreadElement, + isRecord: boolean, protoRef: { used: boolean }, refExpressionErrors: ?ExpressionErrors, ): void { @@ -152,7 +153,7 @@ export default (superClass: Class): Class => if (prop.method) { return; } - super.checkDuplicatedProto(prop, protoRef, refExpressionErrors); + super.checkProto(prop, isRecord, protoRef, refExpressionErrors); } isValidDirective(stmt: N.Statement): boolean {