Skip to content

Commit 5d7817b

Browse files
alexander-akaitjonathantneal
authored andcommitted
fix: unicode surrogate pair parsing
1 parent 9aad10f commit 5d7817b

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

src/__tests__/classes.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,9 @@ test('class selector with escaping (33)', '.f\\+o\\+o', (t, tree) => {
246246
t.deepEqual(tree.nodes[0].nodes[0].type, 'class');
247247
t.deepEqual(tree.nodes[0].nodes[0].raws.value, 'f\\+o\\+o');
248248
});
249+
250+
test('class selector with escaping (34)', '.\\1D306', (t, tree) => {
251+
t.deepEqual(tree.nodes[0].nodes[0].value, '𝌆');
252+
t.deepEqual(tree.nodes[0].nodes[0].type, 'class');
253+
t.deepEqual(tree.nodes[0].nodes[0].raws.value, '\\1D306');
254+
});

src/util/unesc.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1-
const HEX_ESC = /\\(?:([0-9a-fA-F]{6})|([0-9a-fA-F]{1,5})(?: |(?![0-9a-fA-F])))/g;
2-
const OTHER_ESC = /\\(.)/g;
1+
const whitespace = '[\\x20\\t\\r\\n\\f]';
2+
const unescapeRegExp = new RegExp('\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig');
3+
34
export default function unesc (str) {
4-
str = str.replace(HEX_ESC, (_, hex1, hex2) => {
5-
let hex = hex1 || hex2;
6-
let code = parseInt(hex, 16);
7-
return String.fromCharCode(code);
5+
return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
6+
const high = '0x' + escaped - 0x10000;
7+
8+
// NaN means non-codepoint
9+
// Workaround erroneous numeric interpretation of +"0x"
10+
// eslint-disable-next-line no-self-compare
11+
return high !== high || escapedWhitespace
12+
? escaped
13+
: high < 0
14+
? // BMP codepoint
15+
String.fromCharCode(high + 0x10000)
16+
: // Supplemental Plane codepoint (surrogate pair)
17+
String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);
818
});
9-
str = str.replace(OTHER_ESC, (_, char) => char);
10-
return str;
1119
}

0 commit comments

Comments
 (0)