From 38da2eb89df199021349c689fb0024db4c99d6f2 Mon Sep 17 00:00:00 2001 From: Zuo Haocheng Date: Sat, 30 Sep 2017 10:17:39 +0800 Subject: [PATCH] fix: Handle exception on loading invalid base64 source maps (#53) --- index.js | 13 ++++++++++-- test/fixtures/invalid-inline-source-map.js | 3 +++ test/fixtures/invalid-inline-source-map2.js | 3 +++ test/index.test.js | 22 +++++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/invalid-inline-source-map.js create mode 100644 test/fixtures/invalid-inline-source-map2.js diff --git a/index.js b/index.js index 25713fa..5f9fe91 100644 --- a/index.js +++ b/index.js @@ -15,7 +15,7 @@ var baseRegex = "\\s*[@#]\\s*sourceMappingURL\\s*=\\s*([^\\s]*)(?![\\S\\s]*sourc // Matches // .... comments regex2 = new RegExp("//"+baseRegex+"($|\n|\r\n?)"), // Matches DataUrls - regexDataUrl = /data:[^;\n]+(?:;charset=[^;\n]+)?;base64,(.*)/; + regexDataUrl = /data:[^;\n]+(?:;charset=[^;\n]+)?;base64,([a-zA-Z0-9+/]+={0,2})/; module.exports = function(input, inputMap) { this.cacheable && this.cacheable(); @@ -28,7 +28,16 @@ module.exports = function(input, inputMap) { var dataUrlMatch = regexDataUrl.exec(url); var callback = this.async(); if(dataUrlMatch) { - processMap(JSON.parse((new Buffer(dataUrlMatch[1], "base64")).toString()), this.context, callback); + var mapBase64 = dataUrlMatch[1]; + var mapStr = (new Buffer(mapBase64, "base64")).toString(); + var map; + try { + map = JSON.parse(mapStr) + } catch (e) { + emitWarning("Cannot parse inline SourceMap '" + mapBase64.substr(0, 50) + "': " + e); + return untouched(); + } + processMap(map, this.context, callback); } else { resolve(this.context, loaderUtils.urlToRequest(url), function(err, result) { if(err) { diff --git a/test/fixtures/invalid-inline-source-map.js b/test/fixtures/invalid-inline-source-map.js new file mode 100644 index 0000000..f9b7d7c --- /dev/null +++ b/test/fixtures/invalid-inline-source-map.js @@ -0,0 +1,3 @@ +without SourceMap +// @sourceMappingURL=data:application/source-map;base64,"something invalid" +// comment \ No newline at end of file diff --git a/test/fixtures/invalid-inline-source-map2.js b/test/fixtures/invalid-inline-source-map2.js new file mode 100644 index 0000000..1c66752 --- /dev/null +++ b/test/fixtures/invalid-inline-source-map2.js @@ -0,0 +1,3 @@ +without SourceMap +// @sourceMappingURL=data:application/source-map;base64,invalid/base64= +// comment \ No newline at end of file diff --git a/test/index.test.js b/test/index.test.js index ed0543b..0504647 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -127,6 +127,28 @@ describe("source-map-loader", function() { done(); }); }); + it("should skip invalid base64 SourceMap", function (done) { + execLoader(path.join(__dirname, "fixtures", "invalid-inline-source-map.js"), function (err, res, map, deps, warns) { + should.equal(err, null); + warns.should.be.eql([]); + should.equal(res, "without SourceMap\n// @sourceMappingURL=data:application/source-map;base64,\"something invalid\"\n// comment"); + should.equal(map, null); + deps.should.be.eql([]); + done(); + }); + }); + it("should warn on invalid base64 SourceMap", function (done) { + execLoader(path.join(__dirname, "fixtures", "invalid-inline-source-map2.js"), function (err, res, map, deps, warns) { + should.equal(err, null); + warns.should.matchEach( + new RegExp("Cannot parse inline SourceMap 'invalid\/base64=': SyntaxError: Unexpected token") + ); + should.equal(res, "without SourceMap\n// @sourceMappingURL=data:application/source-map;base64,invalid/base64=\n// comment"); + should.equal(map, null); + deps.should.be.eql([]); + done(); + }); + }); it("should warn on missing SourceMap", function(done) { execLoader(path.join(__dirname, "fixtures", "missing-source-map.js"), function(err, res, map, deps, warns) { should.equal(err, null);