fix: non-directive "use strict" should not enable parsing in strict mode (#11188)
* fix: non-directive "use strict" should not enable parsing in strict mode * Remove dead code * Add stricter type annotations * set oldStrict explicitly to null * Fix error * label callback argument * update comment * Address feedback * Remove this.state.octalPosition * Add additional tests * Revert "Remove this.state.octalPosition" This reverts commit bcc78c9530f8c840f85e86053b75efce662f34d1. * Remove containsOctal * Report multiple octal literals in single token * Fix comments * remove Array.prototype.flat()
This commit is contained in:
@@ -55,6 +55,7 @@ export default class ExpressionParser extends LValParser {
|
||||
+parseBlock: (
|
||||
allowDirectives?: boolean,
|
||||
createNewLexicalScope?: boolean,
|
||||
afterBlockParse?: (hasStrictModeDirective: boolean) => void,
|
||||
) => N.BlockStatement;
|
||||
+parseClass: (
|
||||
node: N.Class,
|
||||
@@ -1877,9 +1878,6 @@ export default class ExpressionParser extends LValParser {
|
||||
isMethod?: boolean = false,
|
||||
): void {
|
||||
const isExpression = allowExpression && !this.match(tt.braceL);
|
||||
const oldStrict = this.state.strict;
|
||||
let useStrict = false;
|
||||
|
||||
const oldInParameters = this.state.inParameters;
|
||||
this.state.inParameters = false;
|
||||
|
||||
@@ -1887,58 +1885,63 @@ export default class ExpressionParser extends LValParser {
|
||||
node.body = this.parseMaybeAssign();
|
||||
this.checkParams(node, false, allowExpression, false);
|
||||
} else {
|
||||
const nonSimple = !this.isSimpleParamList(node.params);
|
||||
if (!oldStrict || nonSimple) {
|
||||
useStrict = this.strictDirective(this.state.end);
|
||||
// If this is a strict mode function, verify that argument names
|
||||
// are not repeated, and it does not try to bind the words `eval`
|
||||
// or `arguments`.
|
||||
if (useStrict && nonSimple) {
|
||||
// This logic is here to align the error location with the estree plugin
|
||||
const errorPos =
|
||||
// $FlowIgnore
|
||||
(node.kind === "method" || node.kind === "constructor") &&
|
||||
// $FlowIgnore
|
||||
!!node.key
|
||||
? node.key.end
|
||||
: node.start;
|
||||
this.raise(errorPos, Errors.IllegalLanguageModeDirective);
|
||||
}
|
||||
}
|
||||
const oldStrict = this.state.strict;
|
||||
// Start a new scope with regard to labels
|
||||
// flag (restore them to their old value afterwards).
|
||||
const oldLabels = this.state.labels;
|
||||
this.state.labels = [];
|
||||
if (useStrict) this.state.strict = true;
|
||||
// Add the params to varDeclaredNames to ensure that an error is thrown
|
||||
// if a let/const declaration in the function clashes with one of the params.
|
||||
this.checkParams(
|
||||
node,
|
||||
!oldStrict && !useStrict && !allowExpression && !isMethod && !nonSimple,
|
||||
allowExpression,
|
||||
!oldStrict && useStrict,
|
||||
);
|
||||
|
||||
// FunctionBody[Yield, Await]:
|
||||
// StatementList[?Yield, ?Await, +Return] opt
|
||||
this.prodParam.enter(this.prodParam.currentFlags() | PARAM_RETURN);
|
||||
node.body = this.parseBlock(true, false);
|
||||
node.body = this.parseBlock(
|
||||
true,
|
||||
false,
|
||||
// Strict mode function checks after we parse the statements in the function body.
|
||||
(hasStrictModeDirective: boolean) => {
|
||||
const nonSimple = !this.isSimpleParamList(node.params);
|
||||
|
||||
if (hasStrictModeDirective && nonSimple) {
|
||||
// This logic is here to align the error location with the ESTree plugin.
|
||||
const errorPos =
|
||||
// $FlowIgnore
|
||||
(node.kind === "method" || node.kind === "constructor") &&
|
||||
// $FlowIgnore
|
||||
!!node.key
|
||||
? node.key.end
|
||||
: node.start;
|
||||
this.raise(errorPos, Errors.IllegalLanguageModeDirective);
|
||||
}
|
||||
|
||||
const strictModeChanged = !oldStrict && this.state.strict;
|
||||
|
||||
// Add the params to varDeclaredNames to ensure that an error is thrown
|
||||
// if a let/const declaration in the function clashes with one of the params.
|
||||
this.checkParams(
|
||||
node,
|
||||
!this.state.strict && !allowExpression && !isMethod && !nonSimple,
|
||||
allowExpression,
|
||||
strictModeChanged,
|
||||
);
|
||||
|
||||
// Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
|
||||
if (this.state.strict && node.id) {
|
||||
this.checkLVal(
|
||||
node.id,
|
||||
BIND_OUTSIDE,
|
||||
undefined,
|
||||
"function name",
|
||||
undefined,
|
||||
strictModeChanged,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
this.prodParam.exit();
|
||||
this.state.labels = oldLabels;
|
||||
}
|
||||
|
||||
this.state.inParameters = oldInParameters;
|
||||
// Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
|
||||
if (this.state.strict && node.id) {
|
||||
this.checkLVal(
|
||||
node.id,
|
||||
BIND_OUTSIDE,
|
||||
undefined,
|
||||
"function name",
|
||||
undefined,
|
||||
!oldStrict && useStrict,
|
||||
);
|
||||
}
|
||||
this.state.strict = oldStrict;
|
||||
}
|
||||
|
||||
isSimpleParamList(
|
||||
|
||||
Reference in New Issue
Block a user