improve source map handling (#3464)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 10 Oct 2019 19:52:33 +0000 (03:52 +0800)
committerGitHub <noreply@github.com>
Thu, 10 Oct 2019 19:52:33 +0000 (03:52 +0800)
fixes #2947
fixes #3277
fixes #3411

lib/minify.js
test/input/issue-3441/input.js [new file with mode: 0644]
test/mocha/sourcemaps.js

index 9eebc37..93f1295 100644 (file)
@@ -1,19 +1,39 @@
 "use strict";
 
-var to_ascii = typeof atob == "undefined" ? function(b64) {
-    return new Buffer(b64, "base64").toString();
-} : atob;
-var to_base64 = typeof btoa == "undefined" ? function(str) {
-    return new Buffer(str).toString("base64");
-} : btoa;
+var to_ascii, to_base64;
+if (typeof Buffer == "undefined") {
+    to_ascii = atob;
+    to_base64 = btoa;
+} else if (typeof Buffer.alloc == "undefined") {
+    to_ascii = function(b64) {
+        return new Buffer(b64, "base64").toString();
+    };
+    to_base64 = function(str) {
+        return new Buffer(str).toString("base64");
+    };
+} else {
+    to_ascii = function(b64) {
+        return Buffer.from(b64, "base64").toString();
+    };
+    to_base64 = function(str) {
+        return Buffer.from(str).toString("base64");
+    };
+}
 
-function read_source_map(name, code) {
-    var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(\S+)\s*$/.exec(code);
-    if (!match) {
-        AST_Node.warn("inline source map not found: " + name);
-        return null;
+function read_source_map(name, toplevel) {
+    var comments = toplevel.end.comments_after;
+    for (var i = comments.length; --i >= 0;) {
+        var comment = comments[i];
+        if (comment.type != "comment1") break;
+        var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value);
+        if (!match) break;
+        if (match[1] == "sourceMappingURL") {
+            match = /^data:application\/json(;.*?)?;base64,(\S+)$/.exec(match[2]);
+            if (!match) break;
+            return to_ascii(match[2]);
+        }
     }
-    return to_ascii(match[2]);
+    AST_Node.warn("inline source map not found: " + name);
 }
 
 function parse_source_map(content) {
@@ -134,10 +154,10 @@ function minify(files, options) {
             source_maps = source_map_content && Object.create(null);
             for (var name in files) if (HOP(files, name)) {
                 options.parse.filename = name;
-                options.parse.toplevel = parse(files[name], options.parse);
+                options.parse.toplevel = toplevel = parse(files[name], options.parse);
                 if (source_maps) {
                     if (source_map_content == "inline") {
-                        var inlined_content = read_source_map(name, files[name]);
+                        var inlined_content = read_source_map(name, toplevel);
                         if (inlined_content) {
                             source_maps[name] = parse_source_map(inlined_content);
                         }
@@ -146,7 +166,6 @@ function minify(files, options) {
                     }
                 }
             }
-            toplevel = options.parse.toplevel;
         }
         if (quoted_props) {
             reserve_quoted_keys(toplevel, quoted_props);
diff --git a/test/input/issue-3441/input.js b/test/input/issue-3441/input.js
new file mode 100644 (file)
index 0000000..c9ca8e7
--- /dev/null
@@ -0,0 +1,8 @@
+// Generated by CoffeeScript 2.4.1
+(function() {
+  console.log('hello');
+
+}).call(this);
+
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1haW4uY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtFQUFBLE9BQU8sQ0FBQyxHQUFSLENBQVksT0FBWjtBQUFBIiwic291cmNlc0NvbnRlbnQiOlsiY29uc29sZS5sb2cgJ2hlbGxvJ1xuIl19
+//# sourceURL=/Users/mohamed/Downloads/main.coffee
index 78e100b..aff2b00 100644 (file)
@@ -181,6 +181,18 @@ describe("sourcemaps", function() {
             if (result.error) throw result.error;
             assert.strictEqual(result.code + "\n", readFileSync("test/input/issue-3294/output.js", "utf8"));
         });
+        it("Should work in presence of unrecognised annotations", function() {
+            var result = UglifyJS.minify(read("./test/input/issue-3441/input.js"), {
+                compress: false,
+                mangle: false,
+                sourceMap: {
+                    content: "inline",
+                },
+            });
+            if (result.error) throw result.error;
+            assert.strictEqual(result.code, '(function(){console.log("hello")}).call(this);');
+            assert.strictEqual(result.map, '{"version":3,"sources":["main.coffee"],"names":["console","log"],"mappings":"CAAA,WAAAA,QAAQC,IAAI"}');
+        });
     });
 
     describe("sourceMapInline", function() {