Skip to content

Commit

Permalink
fix: disallow __proto__ in record
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Jun 1, 2020
1 parent 3a85c92 commit 5d91a42
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 6 deletions.
1 change: 1 addition & 0 deletions packages/babel-parser/src/parser/error-message.js
Expand Up @@ -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",
Expand Down
15 changes: 11 additions & 4 deletions packages/babel-parser/src/parser/expression.js
Expand Up @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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 (
Expand Down
5 changes: 3 additions & 2 deletions packages/babel-parser/src/plugins/estree.js
Expand Up @@ -143,16 +143,17 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
}

checkDuplicatedProto(
checkProto(
prop: N.ObjectMember | N.SpreadElement,
isRecord: boolean,
protoRef: { used: boolean },
refExpressionErrors: ?ExpressionErrors,
): void {
// $FlowIgnore: check prop.method and fallback to super method
if (prop.method) {
return;
}
super.checkDuplicatedProto(prop, protoRef, refExpressionErrors);
super.checkProto(prop, isRecord, protoRef, refExpressionErrors);
}

isValidDirective(stmt: N.Statement): boolean {
Expand Down

0 comments on commit 5d91a42

Please sign in to comment.