From 406c3dabc025f5ca89fa3ac1c81200853aa4b3b4 Mon Sep 17 00:00:00 2001 From: Alex Kuzmenko Date: Mon, 3 Apr 2017 23:25:29 +0300 Subject: [PATCH 1/3] Fix number parser (#433) Fixed number parser #2 Added one more test --- src/tokenizer/index.js | 8 ++- .../core/uncategorised/355/expected.json | 69 +++++++++++++++++++ .../core/uncategorised/355/options.json | 3 - .../core/uncategorised/356/expected.json | 69 +++++++++++++++++++ .../core/uncategorised/356/options.json | 3 - .../fixtures/core/uncategorised/550/actual.js | 2 + .../core/uncategorised/550/options.json | 3 + .../fixtures/core/uncategorised/551/actual.js | 1 + .../core/uncategorised/551/expected.json | 69 +++++++++++++++++++ .../fixtures/core/uncategorised/552/actual.js | 2 + .../core/uncategorised/552/options.json | 3 + .../fixtures/core/uncategorised/553/actual.js | 1 + .../core/uncategorised/553/expected.json | 69 +++++++++++++++++++ 13 files changed, 293 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/core/uncategorised/355/expected.json delete mode 100644 test/fixtures/core/uncategorised/355/options.json create mode 100644 test/fixtures/core/uncategorised/356/expected.json delete mode 100644 test/fixtures/core/uncategorised/356/options.json create mode 100644 test/fixtures/core/uncategorised/550/actual.js create mode 100644 test/fixtures/core/uncategorised/550/options.json create mode 100644 test/fixtures/core/uncategorised/551/actual.js create mode 100644 test/fixtures/core/uncategorised/551/expected.json create mode 100644 test/fixtures/core/uncategorised/552/actual.js create mode 100644 test/fixtures/core/uncategorised/552/options.json create mode 100644 test/fixtures/core/uncategorised/553/actual.js create mode 100644 test/fixtures/core/uncategorised/553/expected.json diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index a058ba91a5..076b636381 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -564,7 +564,7 @@ export default class Tokenizer { readNumber(startsWithDot) { const start = this.state.pos; - const octal = this.input.charCodeAt(this.state.pos) === 48; + const firstIsZero = this.input.charCodeAt(start) === 48; // '0' let isFloat = false; if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number"); @@ -587,10 +587,12 @@ export default class Tokenizer { let val; if (isFloat) { val = parseFloat(str); - } else if (!octal || str.length === 1) { + } else if (!firstIsZero || str.length === 1) { val = parseInt(str, 10); - } else if (/[89]/.test(str) || this.state.strict) { + } else if (this.state.strict) { this.raise(start, "Invalid number"); + } else if (/[89]/.test(str)) { + val = parseInt(str, 10); } else { val = parseInt(str, 8); } diff --git a/test/fixtures/core/uncategorised/355/expected.json b/test/fixtures/core/uncategorised/355/expected.json new file mode 100644 index 0000000000..08de8c762b --- /dev/null +++ b/test/fixtures/core/uncategorised/355/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "extra": { + "rawValue": 9, + "raw": "09" + }, + "value": 9 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/355/options.json b/test/fixtures/core/uncategorised/355/options.json deleted file mode 100644 index cf3086295c..0000000000 --- a/test/fixtures/core/uncategorised/355/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Invalid number (1:0)" -} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/356/expected.json b/test/fixtures/core/uncategorised/356/expected.json new file mode 100644 index 0000000000..6d04954399 --- /dev/null +++ b/test/fixtures/core/uncategorised/356/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "extra": { + "rawValue": 18, + "raw": "018" + }, + "value": 18 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/356/options.json b/test/fixtures/core/uncategorised/356/options.json deleted file mode 100644 index cf3086295c..0000000000 --- a/test/fixtures/core/uncategorised/356/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Invalid number (1:0)" -} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/550/actual.js b/test/fixtures/core/uncategorised/550/actual.js new file mode 100644 index 0000000000..64dcf36896 --- /dev/null +++ b/test/fixtures/core/uncategorised/550/actual.js @@ -0,0 +1,2 @@ +'use strict'; +const a = 07; diff --git a/test/fixtures/core/uncategorised/550/options.json b/test/fixtures/core/uncategorised/550/options.json new file mode 100644 index 0000000000..f635fb88c5 --- /dev/null +++ b/test/fixtures/core/uncategorised/550/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Invalid number (2:10)" +} diff --git a/test/fixtures/core/uncategorised/551/actual.js b/test/fixtures/core/uncategorised/551/actual.js new file mode 100644 index 0000000000..524f32795d --- /dev/null +++ b/test/fixtures/core/uncategorised/551/actual.js @@ -0,0 +1 @@ +0111 \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/551/expected.json b/test/fixtures/core/uncategorised/551/expected.json new file mode 100644 index 0000000000..07311dd1eb --- /dev/null +++ b/test/fixtures/core/uncategorised/551/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "extra": { + "rawValue": 73, + "raw": "0111" + }, + "value": 73 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/552/actual.js b/test/fixtures/core/uncategorised/552/actual.js new file mode 100644 index 0000000000..63f4544f72 --- /dev/null +++ b/test/fixtures/core/uncategorised/552/actual.js @@ -0,0 +1,2 @@ +'use strict'; +const a = 08; diff --git a/test/fixtures/core/uncategorised/552/options.json b/test/fixtures/core/uncategorised/552/options.json new file mode 100644 index 0000000000..f635fb88c5 --- /dev/null +++ b/test/fixtures/core/uncategorised/552/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Invalid number (2:10)" +} diff --git a/test/fixtures/core/uncategorised/553/actual.js b/test/fixtures/core/uncategorised/553/actual.js new file mode 100644 index 0000000000..6b07531279 --- /dev/null +++ b/test/fixtures/core/uncategorised/553/actual.js @@ -0,0 +1 @@ +0274134317073 \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/553/expected.json b/test/fixtures/core/uncategorised/553/expected.json new file mode 100644 index 0000000000..756da7f491 --- /dev/null +++ b/test/fixtures/core/uncategorised/553/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "extra": { + "rawValue": 25257156155, + "raw": "0274134317073" + }, + "value": 25257156155 + } + } + ], + "directives": [] + } +} \ No newline at end of file From b98f463aa759979bbed1dd7704e66c7616e89d07 Mon Sep 17 00:00:00 2001 From: Alex Kuzmenko Date: Fri, 21 Apr 2017 16:22:50 +0300 Subject: [PATCH 2/3] Fixed invalid number literal parsing (#473) * Fixed invalid number literal parsing * Don't ignore period or E characters after octal numbers cherry-pick fix from acorn * Fix tests --- src/tokenizer/index.js | 12 ++++++++---- test/fixtures/core/uncategorised/554/actual.js | 1 + test/fixtures/core/uncategorised/554/options.json | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/core/uncategorised/554/actual.js create mode 100644 test/fixtures/core/uncategorised/554/options.json diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 076b636381..4031b008b1 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -564,30 +564,34 @@ export default class Tokenizer { readNumber(startsWithDot) { const start = this.state.pos; - const firstIsZero = this.input.charCodeAt(start) === 48; // '0' + let octal = this.input.charCodeAt(start) === 48; // '0' let isFloat = false; if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number"); + if (octal && this.state.pos == start + 1) octal = false; // number === 0 + let next = this.input.charCodeAt(this.state.pos); - if (next === 46) { // '.' + if (next === 46 && !octal) { // '.' ++this.state.pos; this.readInt(10); isFloat = true; next = this.input.charCodeAt(this.state.pos); } - if (next === 69 || next === 101) { // 'eE' + + if ((next === 69 || next === 101) && !octal) { // 'eE' next = this.input.charCodeAt(++this.state.pos); if (next === 43 || next === 45) ++this.state.pos; // '+-' if (this.readInt(10) === null) this.raise(start, "Invalid number"); isFloat = true; } + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number"); const str = this.input.slice(start, this.state.pos); let val; if (isFloat) { val = parseFloat(str); - } else if (!firstIsZero || str.length === 1) { + } else if (!octal || str.length === 1) { val = parseInt(str, 10); } else if (this.state.strict) { this.raise(start, "Invalid number"); diff --git a/test/fixtures/core/uncategorised/554/actual.js b/test/fixtures/core/uncategorised/554/actual.js new file mode 100644 index 0000000000..204735a64f --- /dev/null +++ b/test/fixtures/core/uncategorised/554/actual.js @@ -0,0 +1 @@ +var a = 0123.; \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/554/options.json b/test/fixtures/core/uncategorised/554/options.json new file mode 100644 index 0000000000..e247a786c1 --- /dev/null +++ b/test/fixtures/core/uncategorised/554/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (1:13)" +} From 1077a7304ea923510e37744a2fba99fad2ae0d11 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Mon, 10 Apr 2017 10:48:51 -0500 Subject: [PATCH 3/3] Fix typo in flow spread operator error [skip ci] --- src/plugins/flow.js | 2 +- test/fixtures/flow/type-annotations/137/options.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 8b63c97207..eac336b2d2 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -451,7 +451,7 @@ pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { if (!allowSpread) { this.unexpected( null, - "Spread operator cannnot appear in class or interface definitions" + "Spread operator cannot appear in class or interface definitions" ); } if (variance) { diff --git a/test/fixtures/flow/type-annotations/137/options.json b/test/fixtures/flow/type-annotations/137/options.json index 79756f8c33..786acad32a 100644 --- a/test/fixtures/flow/type-annotations/137/options.json +++ b/test/fixtures/flow/type-annotations/137/options.json @@ -1,3 +1,3 @@ { - "throws": "Spread operator cannnot appear in class or interface definitions (2:1)" + "throws": "Spread operator cannot appear in class or interface definitions (2:1)" }