From: Alex Lam S.L Date: Wed, 22 Mar 2017 22:11:16 +0000 (+0800) Subject: fix a bug in simple_glob (#1632) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=a00040dd93083548aa065c5ae8942e3c2600cbbe;p=UglifyJS.git fix a bug in simple_glob (#1632) - "?" should not match "/" - other minor clean-ups --- diff --git a/test/input/issue-1632/^{foo}[bar](baz)+$.js b/test/input/issue-1632/^{foo}[bar](baz)+$.js new file mode 100644 index 00000000..f92e3a10 --- /dev/null +++ b/test/input/issue-1632/^{foo}[bar](baz)+$.js @@ -0,0 +1 @@ +console.log(x); \ No newline at end of file diff --git a/test/mocha/glob.js b/test/mocha/glob.js index 30313656..557489c1 100644 --- a/test/mocha/glob.js +++ b/test/mocha/glob.js @@ -1,5 +1,6 @@ var Uglify = require('../../'); var assert = require("assert"); +var path = require("path"); describe("minify() with input file globs", function() { it("minify() with one input file glob string.", function() { @@ -21,4 +22,37 @@ describe("minify() with input file globs", function() { }); assert.strictEqual(result.code, 'var print=console.log.bind(console);print("qux",function(n){return 3*n}(3),function(n){return n/2}(12)),function(n){print("Foo:",2*n)}(11);'); }); + it("should throw with non-matching glob string", function() { + var glob = "test/input/issue-1242/blah.*"; + assert.strictEqual(Uglify.simple_glob(glob).length, 1); + assert.strictEqual(Uglify.simple_glob(glob)[0], glob); + assert.throws(function() { + Uglify.minify(glob); + }, "should throw file not found"); + }); + it('"?" in glob string should not match "/"', function() { + var glob = "test/input?issue-1242/foo.*"; + assert.strictEqual(Uglify.simple_glob(glob).length, 1); + assert.strictEqual(Uglify.simple_glob(glob)[0], glob); + assert.throws(function() { + Uglify.minify(glob); + }, "should throw file not found"); + }); + it("should handle special characters in glob string", function() { + var result = Uglify.minify("test/input/issue-1632/^{*}[???](*)+$.??"); + assert.strictEqual(result.code, "console.log(x);"); + }); + it("should handle array of glob strings - matching and otherwise", function() { + var dir = "test/input/issue-1242"; + var matches = Uglify.simple_glob([ + path.join(dir, "b*.es5"), + path.join(dir, "z*.es5"), + path.join(dir, "*.js"), + ]); + assert.strictEqual(matches.length, 4); + assert.strictEqual(matches[0], path.join(dir, "bar.es5")); + assert.strictEqual(matches[1], path.join(dir, "baz.es5")); + assert.strictEqual(matches[2], path.join(dir, "z*.es5")); + assert.strictEqual(matches[3], path.join(dir, "qux.js")); + }); }); diff --git a/tools/exports.js b/tools/exports.js index 54aa23e8..d83739d5 100644 --- a/tools/exports.js +++ b/tools/exports.js @@ -18,6 +18,6 @@ exports["tokenizer"] = tokenizer; exports["is_identifier"] = is_identifier; exports["SymbolDef"] = SymbolDef; -if (typeof DEBUG !== "undefined" && DEBUG) { +if (global.UGLIFY_DEBUG) { exports["EXPECT_DIRECTIVE"] = EXPECT_DIRECTIVE; } diff --git a/tools/node.js b/tools/node.js index c64b4e5c..6568a741 100644 --- a/tools/node.js +++ b/tools/node.js @@ -7,7 +7,8 @@ var path = require("path"); var fs = require("fs"); -var FILES = exports.FILES = [ +var UglifyJS = exports; +var FILES = UglifyJS.FILES = [ "../lib/utils.js", "../lib/ast.js", "../lib/parse.js", @@ -20,17 +21,14 @@ var FILES = exports.FILES = [ "../lib/propmangle.js", "./exports.js", ].map(function(file){ - return fs.realpathSync(path.join(path.dirname(__filename), file)); + return require.resolve(file); }); -var UglifyJS = exports; - -new Function("MOZ_SourceMap", "exports", "DEBUG", FILES.map(function(file){ +new Function("MOZ_SourceMap", "exports", FILES.map(function(file){ return fs.readFileSync(file, "utf8"); }).join("\n\n"))( require("source-map"), - UglifyJS, - !!global.UGLIFY_DEBUG + UglifyJS ); UglifyJS.AST_Node.warn_function = function(txt) { @@ -46,7 +44,7 @@ function read_source_map(code) { return JSON.parse(new Buffer(match[2], "base64")); } -exports.minify = function(files, options) { +UglifyJS.minify = function(files, options) { options = UglifyJS.defaults(options, { spidermonkey : false, outSourceMap : null, @@ -181,7 +179,7 @@ exports.minify = function(files, options) { }; }; -// exports.describe_ast = function() { +// UglifyJS.describe_ast = function() { // function doitem(ctor) { // var sub = {}; // ctor.SUBCLASSES.forEach(function(ctor){ @@ -195,7 +193,7 @@ exports.minify = function(files, options) { // return doitem(UglifyJS.AST_Node).sub; // } -exports.describe_ast = function() { +UglifyJS.describe_ast = function() { var out = UglifyJS.OutputStream({ beautify: true }); function doitem(ctor) { out.print("AST_" + ctor.TYPE); @@ -249,13 +247,13 @@ function readReservedFile(filename, reserved) { return reserved; } -exports.readReservedFile = readReservedFile; +UglifyJS.readReservedFile = readReservedFile; -exports.readDefaultReservedFile = function(reserved) { - return readReservedFile(path.join(__dirname, "domprops.json"), reserved); +UglifyJS.readDefaultReservedFile = function(reserved) { + return readReservedFile(require.resolve("./domprops.json"), reserved); }; -exports.readNameCache = function(filename, key) { +UglifyJS.readNameCache = function(filename, key) { var cache = null; if (filename) { try { @@ -273,7 +271,7 @@ exports.readNameCache = function(filename, key) { return cache; }; -exports.writeNameCache = function(filename, key, cache) { +UglifyJS.writeNameCache = function(filename, key, cache) { if (filename) { var data; try { @@ -294,13 +292,9 @@ exports.writeNameCache = function(filename, key, cache) { // Example: "foo/bar/*baz??.*.js" // Argument `glob` may be a string or an array of strings. // Returns an array of strings. Garbage in, garbage out. -exports.simple_glob = function simple_glob(glob) { - var results = []; +UglifyJS.simple_glob = function simple_glob(glob) { if (Array.isArray(glob)) { - glob.forEach(function(elem) { - results = results.concat(simple_glob(elem)); - }); - return results; + return [].concat.apply([], glob.map(simple_glob)); } if (glob.match(/\*|\?/)) { var dir = path.dirname(glob); @@ -308,28 +302,19 @@ exports.simple_glob = function simple_glob(glob) { var entries = fs.readdirSync(dir); } catch (ex) {} if (entries) { - var pattern = "^" + (path.basename(glob) - .replace(/\(/g, "\\(") - .replace(/\)/g, "\\)") - .replace(/\{/g, "\\{") - .replace(/\}/g, "\\}") - .replace(/\[/g, "\\[") - .replace(/\]/g, "\\]") - .replace(/\+/g, "\\+") - .replace(/\^/g, "\\^") - .replace(/\$/g, "\\$") + var pattern = "^" + path.basename(glob) + .replace(/[.+^$[\]\\(){}]/g, "\\$&") .replace(/\*/g, "[^/\\\\]*") - .replace(/\./g, "\\.") - .replace(/\?/g, ".")) + "$"; + .replace(/\?/g, "[^/\\\\]") + "$"; var mod = process.platform === "win32" ? "i" : ""; var rx = new RegExp(pattern, mod); - for (var i in entries) { - if (rx.test(entries[i])) - results.push(dir + "/" + entries[i]); - } + var results = entries.filter(function(name) { + return rx.test(name); + }).map(function(name) { + return path.join(dir, name); + }); + if (results.length) return results; } } - if (results.length === 0) - results = [ glob ]; - return results; + return [ glob ]; };