From b179a2459fbe170358089c70b4031f16f58c6eb2 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Tue, 6 Apr 2021 19:23:35 +0100 Subject: [PATCH] parse octal literals correctly (#4843) --- lib/parse.js | 25 ++++++++++++++----------- test/compress/numbers.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/lib/parse.js b/lib/parse.js index 41b61b5a15..bc13b60ebd 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -351,7 +351,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { function read_while(pred) { var ret = "", ch; - while ((ch = peek()) && pred(ch)) ret += next(); + while ((ch = peek()) && pred(ch, ret)) ret += next(); return ret; } @@ -359,24 +359,27 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { js_error(err, filename, S.tokline, S.tokcol, S.tokpos); } + function is_octal(num) { + return /^0[0-7_]+$/.test(num); + } + function read_num(prefix) { var has_e = false, after_e = false, has_x = false, has_dot = prefix == "."; - var num = read_while(function(ch) { - var code = ch.charCodeAt(0); - switch (code) { - case 120: case 88: // xX + var num = read_while(function(ch, str) { + switch (ch) { + case "x": case "X": return has_x ? false : (has_x = true); - case 101: case 69: // eE + case "e": case "E": return has_x ? true : has_e ? false : (has_e = after_e = true); - case 43: case 45: // +- + case "+": case "-": return after_e; - case (after_e = false, 46): // . - return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false; + case (after_e = false, "."): + return has_dot || has_e || has_x || is_octal(str) ? false : (has_dot = true); } - return is_digit(code) || /[_0-9a-fo]/i.test(ch); + return /[_0-9a-dfo]/i.test(ch); }); if (prefix) num = prefix + num; - if (/^0[0-7_]+$/.test(num)) { + if (is_octal(num)) { if (next_token.has_directive("use strict")) parse_error("Legacy octal literals are not allowed in strict mode"); } else { num = num.replace(has_x ? /([1-9a-f]|.0)_(?=[0-9a-f])/gi : /([1-9]|.0)_(?=[0-9])/gi, "$1"); diff --git a/test/compress/numbers.js b/test/compress/numbers.js index dced3f1634..124d86ca2c 100644 --- a/test/compress/numbers.js +++ b/test/compress/numbers.js @@ -104,6 +104,40 @@ parentheses_for_prototype_functions_galio: { expect_stdout: true } +octal: { + beautify = { + beautify: true, + } + input: { + (function() { + console.log(052); + console.log(-052); + + console.log(018); + console.log(-018); + + console.log(052.toFixed(0)); + console.log(-052.toFixed(0)); + + console.log(018..toFixed(0)); + console.log(-018..toFixed(0)); + })(); + } + expect_exact: [ + "(function() {", + " console.log(42);", + " console.log(-42);", + " console.log(18);", + " console.log(-18);", + " console.log(42..toFixed(0));", + " console.log(-42..toFixed(0));", + " console.log(18..toFixed(0));", + " console.log(-18..toFixed(0));", + "})();", + ] + expect_stdout: true +} + comparisons: { options = { comparisons: true,