Skip to content

Commit

Permalink
fix: avoid crash on big data URL source maps
Browse files Browse the repository at this point in the history
  • Loading branch information
cap-Bernardito committed May 16, 2020
1 parent 2da2b2e commit 7f769aa
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 27 deletions.
20 changes: 5 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Expand Up @@ -41,9 +41,11 @@
"webpack": "^4.0.0 || ^5.0.0"
},
"dependencies": {
"neo-async": "^2.6.1",
"data-urls": "^2.0.0",
"loader-utils": "^2.0.0",
"schema-utils": "^2.6.6"
"neo-async": "^2.6.1",
"schema-utils": "^2.6.6",
"whatwg-encoding": "^1.0.5"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
Expand Down
29 changes: 20 additions & 9 deletions src/index.js
Expand Up @@ -7,6 +7,8 @@ import path from 'path';

import validateOptions from 'schema-utils';
import async from 'neo-async';
import parseDataURL from 'data-urls';
import { labelToName, decode } from 'whatwg-encoding';
import { getOptions, urlToRequest } from 'loader-utils';

import schema from './options.json';
Expand All @@ -18,8 +20,6 @@ const baseRegex =
const regex1 = new RegExp(`/\\*${baseRegex}\\s*\\*/`);
// Matches // .... comments
const regex2 = new RegExp(`//${baseRegex}($|\n|\r\n?)`);
// Matches DataUrls
const regexDataUrl = /data:[^;\n]+(?:;charset=[^;\n]+)?;base64,([a-zA-Z0-9+/]+={0,2})/;

export default function loader(input, inputMap) {
const options = getOptions(this);
Expand All @@ -39,20 +39,23 @@ export default function loader(input, inputMap) {
}

const [, url] = match;
const dataUrlMatch = regexDataUrl.exec(url);
const { context, resolve, addDependency, emitWarning } = this;

if (dataUrlMatch) {
const [, mapBase64] = dataUrlMatch;
const mapStr = new Buffer(mapBase64, 'base64').toString();
const dataURL = parseDataURL(url);

const { context, resolve, addDependency, emitWarning } = this;

if (dataURL) {
let map;

try {
map = JSON.parse(mapStr);
dataURL.encodingName =
labelToName(dataURL.mimeType.parameters.get('charset')) || 'UTF-8';

map = decode(dataURL.body, dataURL.encodingName);
map = JSON.parse(map);
} catch (error) {
emitWarning(
`Cannot parse inline SourceMap '${mapBase64.substr(0, 50)}': ${error}`
`Cannot parse inline SourceMap with Charset ${dataURL.encodingName}: ${error}`
);

callback(null, input, inputMap);
Expand All @@ -65,6 +68,14 @@ export default function loader(input, inputMap) {
return;
}

if (url.toLowerCase().indexOf('data:') === 0) {
emitWarning(`Cannot parse inline SourceMap: ${url}`);

callback(null, input, inputMap);

return;
}

resolve(context, urlToRequest(url, true), (resolveError, result) => {
if (resolveError) {
emitWarning(`Cannot find SourceMap '${url}': ${resolveError}`);
Expand Down
2 changes: 1 addition & 1 deletion test/index.test.js
Expand Up @@ -181,7 +181,7 @@ describe('source-map-loader', () => {
expect(map).toBeUndefined();
expect(deps).toEqual([]);
expect(warns).toEqual([
"Cannot parse inline SourceMap 'invalid/base64=': SyntaxError: Unexpected token � in JSON at position 0",
'Cannot parse inline SourceMap: data:application/source-map;base64,invalid/base64=',
]);
done();
}
Expand Down

0 comments on commit 7f769aa

Please sign in to comment.