Skip to content

Commit 1d3b74d

Browse files
committed
Fix handling of unicode in source code
1 parent 424f68c commit 1d3b74d

File tree

5 files changed

+263
-12
lines changed

5 files changed

+263
-12
lines changed

core/index.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ export function renderCSS() {
6565
mappings,
6666
sourcesContent: sources.map(source => state.sourceCache.get(source)),
6767
};
68-
const json = JSON.stringify(map);
69-
const base64 = btoa(json);
68+
const base64 = encodeBase64(JSON.stringify(map));
7069

7170
const comment = `/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64} */`;
7271
return `${rules.join("\n")}\n${comment}`;
@@ -206,9 +205,29 @@ function parseDataUrl(url) {
206205
if (match) {
207206
const sourceMapStart = match[0].length;
208207
const encodedSource = url.substr(sourceMapStart);
209-
const source = atob(encodedSource);
208+
const source = decodeBase64(encodedSource);
210209
return JSON.parse(source);
211210
} else {
212211
throw new Error("The encoding of the inline sourcemap is not supported");
213212
}
214213
}
214+
215+
const encoder = new TextEncoder();
216+
const decoder = new TextDecoder();
217+
218+
function encodeBase64(str) {
219+
return btoa(String.fromCharCode(...encoder.encode(str)));
220+
}
221+
222+
function decodeBase64(str) {
223+
return decoder.decode(toArrayBuffer(atob(str)));
224+
}
225+
226+
function toArrayBuffer(str) {
227+
const buf = new ArrayBuffer(str.length);
228+
const bufView = new Uint8Array(buf);
229+
for (let i = 0; i < str.length; i++) {
230+
bufView[i] = str.charCodeAt(i);
231+
}
232+
return buf;
233+
}

fixtures/app/client.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ function toErrorLikeObject(err) {
1414
const {stack, stacktrace, message} = err;
1515
return {stack, stacktrace, message};
1616
}
17+
18+
// A unicode character: 🤪 to ensure the base64 encoding can handle unicode
19+
// See: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_Unicode_Problem

tests/mapper.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
const SourceMapURL = require("source-map-url");
44
const {SourceMapConsumer} = require("source-map/lib/source-map-consumer");
5-
const {atob} = require("abab");
65

76
module.exports = {
87
getConsumer,
@@ -18,15 +17,24 @@ function getConsumer(src) {
1817
return new SourceMapConsumer(map);
1918
}
2019

20+
/**
21+
* Source maps are not supported in puppeteer so it is not possible
22+
* to test against the built-in source mapping implementation.
23+
*/
24+
2125
function parseDataUrl(url) {
2226
const supportedEncodingRegexp = /^data:application\/json;([\w=:"-]+;)*base64,/;
2327
const match = url.match(supportedEncodingRegexp);
2428
if (match) {
2529
const sourceMapStart = match[0].length;
2630
const encodedSource = url.substr(sourceMapStart);
27-
const source = atob(encodedSource);
31+
const source = decodeBase64(encodedSource);
2832
return JSON.parse(source);
2933
} else {
3034
throw new Error("The encoding of the inline sourcemap is not supported");
3135
}
3236
}
37+
38+
function decodeBase64(str) {
39+
return new Buffer(str, "base64").toString("utf-8");
40+
}

tests/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"test": "node worker.js"
77
},
88
"dependencies": {
9-
"abab": "2.0.0",
109
"css-to-js-sourcemap-fixture-app": "0.0.0-workspace",
1110
"css-to-js-sourcemap-worker": "*",
1211
"get-port": "3.2.0",

0 commit comments

Comments
 (0)