Skip to content

Commit

Permalink
Limit strict mode directive to functions with a simple parameter list
Browse files Browse the repository at this point in the history
Fix #1677
Closes gh-1680
  • Loading branch information
ariya committed Dec 20, 2016
1 parent 721a8dd commit 8391d89
Show file tree
Hide file tree
Showing 52 changed files with 9,667 additions and 134 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -16,7 +16,7 @@ with the help of [many contributors](https://github.com/jquery/esprima/contribut
- Sensible [syntax tree format](https://github.com/estree/estree/blob/master/es5.md) as standardized by [ESTree project](https://github.com/estree/estree)
- Experimental support for [JSX](https://facebook.github.io/jsx/), a syntax extension for [React](https://facebook.github.io/react/)
- Optional tracking of syntax node location (index-based and line-column)
- [Heavily tested](http://esprima.org/test/ci.html) (~1400 [unit tests](https://github.com/jquery/esprima/tree/master/test/fixtures) with [full code coverage](https://codecov.io/github/jquery/esprima))
- [Heavily tested](http://esprima.org/test/ci.html) (~1500 [unit tests](https://github.com/jquery/esprima/tree/master/test/fixtures) with [full code coverage](https://codecov.io/github/jquery/esprima))

### API

Expand Down
1 change: 1 addition & 0 deletions src/messages.ts
Expand Up @@ -13,6 +13,7 @@ export const Messages = {
IllegalContinue: 'Illegal continue statement',
IllegalExportDeclaration: 'Unexpected token',
IllegalImportDeclaration: 'Unexpected token',
IllegalLanguageModeDirective: 'Illegal \'use strict\' directive in function with non-simple parameter list',
IllegalReturn: 'Illegal return statement',
InvalidEscapedReservedWord: 'Keyword must not contain escaped characters',
InvalidHexEscapeSequence: 'Invalid hexadecimal escape sequence',
Expand Down
27 changes: 27 additions & 0 deletions src/parser.ts
Expand Up @@ -18,6 +18,7 @@ interface Config {
interface Context {
isModule: boolean;
allowIn: boolean;
allowStrictDirective: boolean;
allowYield: boolean;
await: boolean;
firstCoverInitializedNameError: any;
Expand Down Expand Up @@ -125,6 +126,7 @@ export class Parser {
isModule: false,
await: false,
allowIn: true,
allowStrictDirective: true,
allowYield: true,
firstCoverInitializedNameError: null,
isAssignmentTarget: false,
Expand Down Expand Up @@ -725,6 +727,8 @@ export class Parser {
this.context.isBindingElement = false;

const previousStrict = this.context.strict;
const previousAllowStrictDirective = this.context.allowStrictDirective;
this.context.allowStrictDirective = params.simple;
const body = this.isolateCoverGrammar(this.parseFunctionSourceElements);
if (this.context.strict && params.firstRestricted) {
this.tolerateUnexpectedToken(params.firstRestricted, params.message);
Expand All @@ -733,6 +737,7 @@ export class Parser {
this.tolerateUnexpectedToken(params.stricted, params.message);
}
this.context.strict = previousStrict;
this.context.allowStrictDirective = previousAllowStrictDirective;

return body;
}
Expand Down Expand Up @@ -1560,6 +1565,7 @@ export class Parser {
default:
break;
}
options.simple = options.simple && (param instanceof Node.Identifier);
}

reinterpretAsCoverFormalsList(expr) {
Expand All @@ -1579,6 +1585,7 @@ export class Parser {
}

options = {
simple: true,
paramSet: {}
};

Expand Down Expand Up @@ -1616,6 +1623,7 @@ export class Parser {
}

return {
simple: options.simple,
params: params,
stricted: options.stricted,
firstRestricted: options.firstRestricted,
Expand Down Expand Up @@ -1657,6 +1665,9 @@ export class Parser {
this.context.firstCoverInitializedNameError = null;

const previousStrict = this.context.strict;
const previousAllowStrictDirective = this.context.allowStrictDirective;
this.context.allowStrictDirective = list.simple;

const previousAllowYield = this.context.allowYield;
const previousAwait = this.context.await;
this.context.allowYield = true;
Expand All @@ -1678,6 +1689,7 @@ export class Parser {
this.finalize(node, new Node.ArrowFunctionExpression(list.params, body, expression));

this.context.strict = previousStrict;
this.context.allowStrictDirective = previousAllowStrictDirective;
this.context.allowYield = previousAllowYield;
this.context.await = previousAwait;
}
Expand Down Expand Up @@ -2769,20 +2781,23 @@ export class Parser {
param = this.parseRestElement(params);
this.validateParam(options, param.argument, param.argument.name);
options.params.push(param);
options.simple = false;
return;
}

param = this.parsePatternWithDefault(params);
for (let i = 0; i < params.length; i++) {
this.validateParam(options, params[i], params[i].value);
}
options.simple = options.simple && (param instanceof Node.Identifier);
options.params.push(param);
}

parseFormalParameters(firstRestricted?) {
let options;

options = {
simple: true,
params: [],
firstRestricted: firstRestricted
};
Expand All @@ -2804,6 +2819,7 @@ export class Parser {
this.expect(')');

return {
simple: options.simple,
params: options.params,
stricted: options.stricted,
firstRestricted: options.firstRestricted,
Expand Down Expand Up @@ -2880,6 +2896,8 @@ export class Parser {
}

const previousStrict = this.context.strict;
const previousAllowStrictDirective = this.context.allowStrictDirective;
this.context.allowStrictDirective = formalParameters.simple;
const body = this.parseFunctionSourceElements();
if (this.context.strict && firstRestricted) {
this.throwUnexpectedToken(firstRestricted, message);
Expand All @@ -2889,6 +2907,7 @@ export class Parser {
}

this.context.strict = previousStrict;
this.context.allowStrictDirective = previousAllowStrictDirective;
this.context.await = previousAllowAwait;
this.context.allowYield = previousAllowYield;

Expand Down Expand Up @@ -2947,6 +2966,8 @@ export class Parser {
}

const previousStrict = this.context.strict;
const previousAllowStrictDirective = this.context.allowStrictDirective;
this.context.allowStrictDirective = formalParameters.simple;
const body = this.parseFunctionSourceElements();
if (this.context.strict && firstRestricted) {
this.throwUnexpectedToken(firstRestricted, message);
Expand All @@ -2955,6 +2976,7 @@ export class Parser {
this.tolerateUnexpectedToken(stricted, message);
}
this.context.strict = previousStrict;
this.context.allowStrictDirective = previousAllowStrictDirective;
this.context.await = previousAllowAwait;
this.context.allowYield = previousAllowYield;

Expand Down Expand Up @@ -2997,6 +3019,9 @@ export class Parser {
if (firstRestricted) {
this.tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral);
}
if (!this.context.allowStrictDirective) {
this.tolerateUnexpectedToken(token, Messages.IllegalLanguageModeDirective);
}
} else {
if (!firstRestricted && token.octal) {
firstRestricted = token;
Expand Down Expand Up @@ -3033,6 +3058,7 @@ export class Parser {

const isGenerator = false;
const params = {
simple: true,
params: [],
stricted: null,
firstRestricted: null,
Expand All @@ -3050,6 +3076,7 @@ export class Parser {
const node = this.createNode();

let options = {
simple: true,
params: [],
firstRestricted: null,
paramSet: {}
Expand Down
@@ -0,0 +1 @@
([]) => { "use strict" }

0 comments on commit 8391d89

Please sign in to comment.