From d90777b724689af625c36ed6d557b024775ee95a Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Fri, 15 Mar 2019 00:20:20 +0800 Subject: [PATCH] parse `mangle.properties.regex` in `--config-file` properly (#3337) fixes #3315 --- bin/uglifyjs | 19 ++++++++----------- lib/parse.js | 29 ++++++++++++++++------------- test/input/issue-3315/config.json | 8 ++++++++ test/input/issue-3315/input.js | 8 ++++++++ test/mocha/cli.js | 24 ++++++++++++++++-------- test/mocha/comments.js | 4 ++-- test/mocha/directives.js | 2 +- test/mocha/getter-setter.js | 2 +- test/mocha/minify.js | 6 +++--- 9 files changed, 63 insertions(+), 39 deletions(-) create mode 100644 test/input/issue-3315/config.json create mode 100644 test/input/issue-3315/input.js diff --git a/bin/uglifyjs b/bin/uglifyjs index 62c7beb3..bee6b6a3 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -56,6 +56,11 @@ program.option("--wrap ", "Embed everything as a function with “exports program.arguments("[files...]").parseArgv(process.argv); if (program.configFile) { options = JSON.parse(read_file(program.configFile)); + if (options.mangle && options.mangle.properties && options.mangle.properties.regex) { + options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, { + expression: true + }).getValue(); + } } if (!program.output && program.sourceMap && program.sourceMap.url != "inline") { fatal("ERROR: cannot write source map to STDOUT"); @@ -337,17 +342,9 @@ function parse_js(flag) { return function(value, options) { options = options || {}; try { - UglifyJS.minify(value, { - parse: { - expression: true - }, - compress: false, - mangle: false, - output: { - ast: true, - code: false - } - }).ast.walk(new UglifyJS.TreeWalker(function(node) { + UglifyJS.parse(value, { + expression: true + }).walk(new UglifyJS.TreeWalker(function(node) { if (node instanceof UglifyJS.AST_Assign) { var name = node.left.print_to_string(); var value = node.right; diff --git a/lib/parse.js b/lib/parse.js index 29df370c..a58557dd 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -758,17 +758,21 @@ function parse($TEXT, options) { croak(msg, token.line, token.col); } + function token_to_string(type, value) { + return type + (value === undefined ? "" : " «" + value + "»"); + } + function unexpected(token) { if (token == null) token = S.token; - token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")"); + token_error(token, "Unexpected token: " + token_to_string(token.type, token.value)); } function expect_token(type, val) { if (is(type, val)) { return next(); } - token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»"); + token_error(S.token, "Unexpected token: " + token_to_string(S.token.type, S.token.value) + ", expected: " + token_to_string(type, val)); } function expect(punc) { @@ -788,7 +792,7 @@ function parse($TEXT, options) { function semicolon(optional) { if (is("punc", ";")) next(); - else if (!optional && !can_insert_semicolon()) unexpected(); + else if (!optional && !can_insert_semicolon()) expect_token("punc", ";"); } function parenthesised() { @@ -1069,7 +1073,7 @@ function parse($TEXT, options) { var in_statement = ctor === AST_Defun; var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null; if (in_statement && !name) - unexpected(); + expect_token("name"); if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration)) unexpected(prev()); expect("("); @@ -1119,7 +1123,7 @@ function parse($TEXT, options) { expect("{"); var a = []; while (!is("punc", "}")) { - if (is("eof")) unexpected(); + if (is("eof")) expect_token("punc", "}"); a.push(statement(strict_defun)); } next(); @@ -1130,7 +1134,7 @@ function parse($TEXT, options) { expect("{"); var a = [], cur = null, branch = null, tmp; while (!is("punc", "}")) { - if (is("eof")) unexpected(); + if (is("eof")) expect_token("punc", "}"); if (is("keyword", "case")) { if (branch) branch.end = prev(); cur = []; @@ -1141,8 +1145,7 @@ function parse($TEXT, options) { }); a.push(branch); expect(":"); - } - else if (is("keyword", "default")) { + } else if (is("keyword", "default")) { if (branch) branch.end = prev(); cur = []; branch = new AST_Default({ @@ -1150,8 +1153,7 @@ function parse($TEXT, options) { body : cur }); a.push(branch); - } - else { + } else { if (!cur) unexpected(); cur.push(statement()); } @@ -1420,10 +1422,10 @@ function parse($TEXT, options) { } function as_name() { - var tmp = S.token; - if (tmp.type != "name") unexpected(); + if (!is("name")) expect_token("name"); + var name = S.token.value; next(); - return tmp.value; + return name; } function _make_symbol(type) { @@ -1625,6 +1627,7 @@ function parse($TEXT, options) { } if (options.expression) { + handle_regexp(); return expression(true); } diff --git a/test/input/issue-3315/config.json b/test/input/issue-3315/config.json new file mode 100644 index 00000000..4bcbaed9 --- /dev/null +++ b/test/input/issue-3315/config.json @@ -0,0 +1,8 @@ +{ + "compress": false, + "mangle": { + "properties": { + "regex": "/^_/" + } + } +} diff --git a/test/input/issue-3315/input.js b/test/input/issue-3315/input.js new file mode 100644 index 00000000..5013fc2f --- /dev/null +++ b/test/input/issue-3315/input.js @@ -0,0 +1,8 @@ +function f() { + "aaaaaaaaaa"; + var o = { + prop: 1, + _int: 2, + }; + return o.prop + o._int; +} diff --git a/test/mocha/cli.js b/test/mocha/cli.js index 1e27f64e..af537f37 100644 --- a/test/mocha/cli.js +++ b/test/mocha/cli.js @@ -257,7 +257,7 @@ describe("bin/uglifyjs", function() { assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12"); assert.strictEqual(lines[1], "function f(a{}"); assert.strictEqual(lines[2], " ^"); - assert.strictEqual(lines[3], "ERROR: Unexpected token punc «{», expected punc «,»"); + assert.strictEqual(lines[3], "ERROR: Unexpected token: punc «{», expected: punc «,»"); done(); }); }); @@ -281,7 +281,7 @@ describe("bin/uglifyjs", function() { assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0"); assert.strictEqual(lines[1], "foo, bar("); assert.strictEqual(lines[2], " ^"); - assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)"); + assert.strictEqual(lines[3], "ERROR: Unexpected token: eof"); done(); }); }); @@ -293,7 +293,7 @@ describe("bin/uglifyjs", function() { assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0"); assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) "); assert.strictEqual(lines[2], " ^"); - assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)"); + assert.strictEqual(lines[3], "ERROR: Unexpected token: eof"); done(); }); }); @@ -362,7 +362,7 @@ describe("bin/uglifyjs", function() { "Parse error at test/input/invalid/dot_1.js:1,2", "a.=", " ^", - "ERROR: Unexpected token: operator (=)" + "ERROR: Unexpected token: operator «=», expected: name" ].join("\n")); done(); }); @@ -376,7 +376,7 @@ describe("bin/uglifyjs", function() { "Parse error at test/input/invalid/dot_2.js:1,0", "%.a;", "^", - "ERROR: Unexpected token: operator (%)" + "ERROR: Unexpected token: operator «%»" ].join("\n")); done(); }); @@ -390,7 +390,7 @@ describe("bin/uglifyjs", function() { "Parse error at test/input/invalid/dot_3.js:1,2", "a./();", " ^", - "ERROR: Unexpected token: operator (/)" + "ERROR: Unexpected token: operator «/», expected: name" ].join("\n")); done(); }); @@ -404,7 +404,7 @@ describe("bin/uglifyjs", function() { "Parse error at test/input/invalid/object.js:1,13", "console.log({%: 1});", " ^", - "ERROR: Unexpected token: operator (%)" + "ERROR: Unexpected token: operator «%»" ].join("\n")); done(); }); @@ -502,7 +502,7 @@ describe("bin/uglifyjs", function() { "Parse error at test/input/invalid/else.js:1,7", "if (0) else 1;", " ^", - "ERROR: Unexpected token: keyword (else)" + "ERROR: Unexpected token: keyword «else»" ].join("\n")); done(); }); @@ -633,6 +633,14 @@ describe("bin/uglifyjs", function() { done(); }); }); + it("Should work with mangle.properties.regex from --config-file", function(done) { + var command = uglifyjscmd + " test/input/issue-3315/input.js --config-file test/input/issue-3315/config.json"; + exec(command, function(err, stdout) { + if (err) throw err; + assert.strictEqual(stdout, 'function f(){"aaaaaaaaaa";var a={prop:1,a:2};return a.prop+a.a}\n'); + done(); + }); + }); it("Should fail with --define a-b", function(done) { var command = uglifyjscmd + " test/input/issue-505/input.js --define a-b"; exec(command, function(err, stdout, stderr) { diff --git a/test/mocha/comments.js b/test/mocha/comments.js index b350a406..1ca1432a 100644 --- a/test/mocha/comments.js +++ b/test/mocha/comments.js @@ -13,7 +13,7 @@ describe("comments", function() { var fail = function(e) { return e instanceof UglifyJS.JS_Parse_Error - && e.message === "Unexpected token: operator (>)" + && e.message === "Unexpected token: operator «>»" && e.line === 2 && e.col === 0; } @@ -36,7 +36,7 @@ describe("comments", function() { var fail = function(e) { return e instanceof UglifyJS.JS_Parse_Error - && e.message === "Unexpected token: operator (>)" + && e.message === "Unexpected token: operator «>»" && e.line === 5 && e.col === 0; } diff --git a/test/mocha/directives.js b/test/mocha/directives.js index 65da6da5..74660dc6 100644 --- a/test/mocha/directives.js +++ b/test/mocha/directives.js @@ -146,7 +146,7 @@ describe("Directives", function() { UglifyJS.parse(tokenizer); }, function(e) { return e instanceof UglifyJS.JS_Parse_Error - && e.message === "Unexpected token: punc (])" + && /^Unexpected token: punc «]»/.test(e.message) }, test[0]); test[1].forEach(function(directive) { assert.strictEqual(tokenizer.has_directive(directive), true, directive + " in " + test[0]); diff --git a/test/mocha/getter-setter.js b/test/mocha/getter-setter.js index 84e7e30d..ec811aa1 100644 --- a/test/mocha/getter-setter.js +++ b/test/mocha/getter-setter.js @@ -69,7 +69,7 @@ describe("Getters and setters", function() { var fail = function(data) { return function(e) { return e instanceof UglifyJS.JS_Parse_Error - && e.message === "Unexpected token: operator (" + data.operator + ")"; + && e.message === "Unexpected token: operator «" + data.operator + "»"; }; }; var errorMessage = function(data) { diff --git a/test/mocha/minify.js b/test/mocha/minify.js index c580e59c..6e6c7a78 100644 --- a/test/mocha/minify.js +++ b/test/mocha/minify.js @@ -119,7 +119,7 @@ describe("minify", function() { it("Should not parse invalid use of reserved words", function() { assert.strictEqual(UglifyJS.minify("function enum(){}").error, undefined); assert.strictEqual(UglifyJS.minify("function static(){}").error, undefined); - assert.strictEqual(UglifyJS.minify("function this(){}").error.message, "Unexpected token: name (this)"); + assert.strictEqual(UglifyJS.minify("function this(){}").error.message, "Unexpected token: name «this»"); }); describe("keep_quoted_props", function() { @@ -214,7 +214,7 @@ describe("minify", function() { var result = UglifyJS.minify("function f(a{}"); var err = result.error; assert.ok(err instanceof Error); - assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»"); + assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: punc «{», expected: punc «,»"); assert.strictEqual(err.filename, "0"); assert.strictEqual(err.line, 1); assert.strictEqual(err.col, 12); @@ -241,7 +241,7 @@ describe("minify", function() { }); var err = result.error; assert.ok(err instanceof Error); - assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword (debugger)"); + assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword «debugger»"); }); it("Should skip inherited properties", function() { var foo = Object.create({ skip: this }); -- 2.34.1