diff --git a/src/lex.js b/src/lex.js index 9a078ea79a..efd8c76446 100644 --- a/src/lex.js +++ b/src/lex.js @@ -752,6 +752,7 @@ Lexer.prototype = { var isAllowedDigit = isDecimalDigit; var base = 10; var isLegacy = false; + var isNonOctal = false; function isDecimalDigit(str) { return (/^[0-9]$/).test(str); @@ -761,6 +762,10 @@ Lexer.prototype = { return (/^[0-7]$/).test(str); } + function isNonOctalDigit(str) { + return str === "8" || str === "9"; + } + function isBinaryDigit(str) { return (/^[01]$/).test(str); } @@ -843,25 +848,22 @@ Lexer.prototype = { base = 8; isLegacy = true; - index += 1; - value += char; - } - - // Decimal numbers that start with '0' such as '09' are illegal - // but we still parse them and return as malformed. - - if (!isOctalDigit(char) && isDecimalDigit(char)) { - index += 1; - value += char; + } else if (isDecimalDigit(char)) { + isNonOctal = true; } } while (index < length) { char = this.peek(index); - // Numbers like '019' (note the 9) are not valid octals - // but we still parse them and mark as malformed. - if (!(isLegacy && isDecimalDigit(char)) && !isAllowedDigit(char)) { + if (isLegacy && isNonOctalDigit(char)) { + base = 10; + isLegacy = false; + isNonOctal = true; + isAllowedDigit = isDecimalDigit; + } + + if (!isAllowedDigit(char)) { break; } value += char; @@ -978,6 +980,7 @@ Lexer.prototype = { type: Token.NumericLiteral, value: value, base: base, + isNonOctal: isNonOctal, isMalformed: false }; }, @@ -2174,6 +2177,14 @@ Lexer.prototype = { return state.isStrict() && token.base === 8 && token.isLegacy; }); + this.triggerAsync("error", { + code: "E068", + line: this.line, + character: this.char + }, checks, function() { + return state.isStrict() && token.isNonOctal; + }); + this.trigger("Number", { line: this.line, char: this.char, diff --git a/src/messages.js b/src/messages.js index e541cdeb19..6c4bd053e2 100644 --- a/src/messages.js +++ b/src/messages.js @@ -83,7 +83,8 @@ var errors = { E065: "Functions defined outside of strict mode with non-simple parameter lists may not " + "enable strict mode.", E066: "Asynchronous iteration is only available with for-of loops.", - E067: "Malformed numeric literal: '{a}'." + E067: "Malformed numeric literal: '{a}'.", + E068: "Decimals with leading zeros are not allowed in strict mode." }; var warnings = { diff --git a/tests/test262/expectations.txt b/tests/test262/expectations.txt index dc934a124e..6740c73ca9 100644 --- a/tests/test262/expectations.txt +++ b/tests/test262/expectations.txt @@ -145,7 +145,6 @@ test/language/identifiers/vals-rus-alpha-upper-via-escape-hex.js(default) test/language/identifiers/vals-rus-alpha-upper-via-escape-hex.js(strict mode) test/language/arguments-object/10.6-13-c-1-s.js(strict mode) test/language/arguments-object/10.6-2gs.js(strict mode) -test/language/literals/numeric/non-octal-decimal-integer-strict.js(strict mode) test/language/block-scope/syntax/function-declarations/in-statement-position-if-expression-statement-else-statement.js(strict mode) test/language/block-scope/syntax/function-declarations/in-statement-position-if-expression-statement.js(strict mode) test/language/destructuring/binding/syntax/array-elements-with-initializer.js(default) diff --git a/tests/unit/parser.js b/tests/unit/parser.js index c1c8159237..85ec611905 100644 --- a/tests/unit/parser.js +++ b/tests/unit/parser.js @@ -568,6 +568,30 @@ exports.numbers = function (test) { "}());" ]); + TestRun(test) + .test([ + "void 08;", + "void 0181;" + ]); + + TestRun(test) + .addError(3, 10, "Decimals with leading zeros are not allowed in strict mode.") + .test([ + "(function () {", + "'use strict';", + "return 08;", + "}());" + ]); + + TestRun(test) + .addError(3, 12, "Decimals with leading zeros are not allowed in strict mode.") + .test([ + "(function () {", + "'use strict';", + "return 0181;", + "}());" + ]); + // GitHub #751 - an expression containing a number with a leading decimal point should be parsed in its entirety TestRun(test) .addError(1, 11, "A leading decimal point can be confused with a dot: '.3'.")