From 3b5ab023bc93152c1715447e4ec4bc5a3d7b70a7 Mon Sep 17 00:00:00 2001 From: Evilebot Tnawi Date: Thu, 12 Apr 2018 17:02:57 +0300 Subject: [PATCH] fix: don't handle invalid source map (#268) --- src/index.js | 14 ++++++++++-- src/utils/index.js | 13 +++++++++++ .../source-map-options.test.js.snap | 16 ++++++++++++++ test/parallel-options.test.js | 8 ++++--- test/source-map-options.test.js | 22 +++++++++++++++---- test/utils/index.test.js | 21 ++++++++++++++++++ 6 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 src/utils/index.js create mode 100644 test/utils/index.test.js diff --git a/src/index.js b/src/index.js index ae7d4ea0..8fbc20d4 100644 --- a/src/index.js +++ b/src/index.js @@ -12,6 +12,7 @@ import serialize from 'serialize-javascript'; import schema from './options.json'; import Uglify from './uglify'; import versions from './uglify/versions'; +import utils from './utils'; const warningRegex = /\[.+:([0-9]+),([0-9]+)\]/; @@ -122,9 +123,18 @@ class UglifyJsPlugin { const { source, map } = asset.sourceAndMap(); input = source; - inputSourceMap = map; - sourceMap = new SourceMapConsumer(inputSourceMap); + if (utils.isSourceMap(map)) { + inputSourceMap = map; + sourceMap = new SourceMapConsumer(inputSourceMap); + } else { + inputSourceMap = map; + sourceMap = null; + + compilation.warnings.push( + new Error(`${file} contain invalid source map`), + ); + } } else { input = asset.source(); inputSourceMap = null; diff --git a/src/utils/index.js b/src/utils/index.js new file mode 100644 index 00000000..37b63c9f --- /dev/null +++ b/src/utils/index.js @@ -0,0 +1,13 @@ +function isSourceMap(input) { + // All required options for `new SourceMapConsumer(...options)` + // https://github.com/mozilla/source-map#new-sourcemapconsumerrawsourcemap + return Boolean(input && + input.version && + input.sources && + input.names && + input.mappings); +} + +export default { + isSourceMap, +}; diff --git a/test/__snapshots__/source-map-options.test.js.snap b/test/__snapshots__/source-map-options.test.js.snap index d533ac50..bd9bd406 100644 --- a/test/__snapshots__/source-map-options.test.js.snap +++ b/test/__snapshots__/source-map-options.test.js.snap @@ -1,5 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`when options.sourceMap true and options.parallel true compilation handler when called optimize-chunk-assets handler only calls callback once: errors 1`] = `Array []`; + +exports[`when options.sourceMap true and options.parallel true compilation handler when called optimize-chunk-assets handler only calls callback once: warnings 1`] = ` +Array [ + [Error: test4.js contain invalid source map], +] +`; + exports[`when options.sourceMap true and options.parallel true matches snapshot: asset main.c26a2e0fdba39d045bc6.js 1`] = `"webpackJsonp([0],[function(o,n){o.exports=function(){console.log(7)}}],[0]);"`; exports[`when options.sourceMap true and options.parallel true matches snapshot: asset manifest.d6857f782c13a99b5917.js 1`] = `"!function(i){var p=window.webpackJsonp;window.webpackJsonp=function(r,n,e){for(var o,t,u,c=0,f=[];c { beforeEach(() => { chunkPluginEnvironment = new PluginEnvironment(); compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; + compilation.assets = Object.assign({}, assets); compilation.errors = []; workerFarm.mockClear(); @@ -183,7 +183,8 @@ describe('when options.parallel', () => { beforeEach(() => { chunkPluginEnvironment = new PluginEnvironment(); compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; + compilation.assets = Object.assign({}, assets); + compilation.warnings = []; compilation.errors = []; workerFarm.mockClear(); @@ -290,7 +291,8 @@ describe('when options.parallel', () => { beforeEach(() => { chunkPluginEnvironment = new PluginEnvironment(); compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; + compilation.assets = Object.assign({}, assets); + compilation.warnings = []; compilation.errors = []; workerFarm.mockClear(); diff --git a/test/source-map-options.test.js b/test/source-map-options.test.js index 2342898b..1c220f0d 100644 --- a/test/source-map-options.test.js +++ b/test/source-map-options.test.js @@ -20,6 +20,14 @@ describe('when options.sourceMap', () => { 'test3.js': { source: () => 'function test3(foo) { foo = 1; }', }, + 'test4.js': { + sourceAndMap: () => { + return { + source: 'function foo(x) { if (x) { return bar(); not_called1(); } }', + map: null, + }; + }, + }, }; describe('true', () => { @@ -62,7 +70,8 @@ describe('when options.sourceMap', () => { beforeEach(() => { chunkPluginEnvironment = new PluginEnvironment(); compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; + compilation.assets = Object.assign({}, assets); + compilation.warnings = []; compilation.errors = []; eventBinding.handler(compilation); @@ -107,8 +116,10 @@ describe('when options.sourceMap', () => { it('only calls callback once', (done) => { callback = jest.fn(); compilationEventBinding.handler([{ - files: ['test.js', 'test1.js', 'test2.js', 'test3.js'], + files: ['test.js', 'test1.js', 'test2.js', 'test3.js', 'test4.js'], }], () => { + expect(compilation.warnings).toMatchSnapshot('warnings'); + expect(compilation.errors).toMatchSnapshot('errors'); callback(); expect(callback.mock.calls.length).toBe(1); done(); @@ -183,7 +194,8 @@ describe('when options.sourceMap', () => { beforeEach(() => { chunkPluginEnvironment = new PluginEnvironment(); compilation = chunkPluginEnvironment.getEnvironmentStub(); - compilation.assets = assets; + compilation.assets = Object.assign({}, assets); + compilation.warnings = []; compilation.errors = []; eventBinding.handler(compilation); @@ -228,8 +240,10 @@ describe('when options.sourceMap', () => { it('only calls callback once', (done) => { callback = jest.fn(); compilationEventBinding.handler([{ - files: ['test.js', 'test1.js', 'test2.js', 'test3.js'], + files: ['test.js', 'test1.js', 'test2.js', 'test3.js', 'test4.js'], }], () => { + expect(compilation.warnings).toMatchSnapshot('warnings'); + expect(compilation.errors).toMatchSnapshot('errors'); callback(); expect(callback.mock.calls.length).toBe(1); done(); diff --git a/test/utils/index.test.js b/test/utils/index.test.js new file mode 100644 index 00000000..3899b084 --- /dev/null +++ b/test/utils/index.test.js @@ -0,0 +1,21 @@ +import utils from '../../src/utils'; + +describe('utils', () => { + it('isSourceMap', () => { + const rawSourceMap = { + version: 3, + file: 'min.js', + names: ['bar', 'baz', 'n'], + sources: ['one.js', 'two.js'], + sourceRoot: 'http://example.com/www/js/', + mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA', + }; + + expect(utils.isSourceMap(null)).toBe(false); + expect(utils.isSourceMap()).toBe(false); + expect(utils.isSourceMap({})).toBe(false); + expect(utils.isSourceMap([])).toBe(false); + expect(utils.isSourceMap('foo')).toBe(false); + expect(utils.isSourceMap(rawSourceMap)).toBe(true); + }); +});