fix: correctly parse escaped unicode characters in css selector

pull/15976/head
7nik 4 months ago
parent ef48d35a15
commit 5877d1a64d

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: correctly parse escaped unicode characters in css selector

@ -12,6 +12,7 @@ const REGEX_NTH_OF =
const REGEX_WHITESPACE_OR_COLON = /[\s:]/;
const REGEX_LEADING_HYPHEN_OR_DIGIT = /-?\d/;
const REGEX_VALID_IDENTIFIER_CHAR = /[a-zA-Z0-9_-]/;
const REGEX_UNICODE_SEQUENCE = /^\\[0-9a-fA-F]{1,6}(\r\n|\s)?/;
const REGEX_COMMENT_CLOSE = /\*\//;
const REGEX_HTML_COMMENT_CLOSE = /-->/;
@ -580,25 +581,26 @@ function read_identifier(parser) {
e.css_expected_identifier(start);
}
let escaped = false;
while (parser.index < parser.template.length) {
const char = parser.template[parser.index];
if (escaped) {
identifier += '\\' + char;
escaped = false;
} else if (char === '\\') {
escaped = true;
if (char === '\\') {
const sequence = parser.match_regex(REGEX_UNICODE_SEQUENCE);
if (sequence) {
identifier += String.fromCodePoint(parseInt(sequence.slice(1), 16));
parser.index += sequence.length;
} else {
identifier += '\\' + parser.template[parser.index + 1];
parser.index += 2;
}
} else if (
/** @type {number} */ (char.codePointAt(0)) >= 160 ||
REGEX_VALID_IDENTIFIER_CHAR.test(char)
) {
identifier += char;
parser.index++;
} else {
break;
}
parser.index++;
}
if (identifier === '') {

@ -0,0 +1,76 @@
import { test } from '../../test';
export default test({
warnings: [
{
code: 'css_unused_selector',
message: 'Unused CSS selector ".\\61 sdf"',
start: {
line: 22,
column: 1,
character: 465
},
end: {
line: 22,
column: 10,
character: 474
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector ".\\61\n\tsdf"',
start: {
line: 23,
column: 1,
character: 492
},
end: {
line: 24,
column: 4,
character: 501
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector ".\\61\n sdf"',
start: {
line: 25,
column: 1,
character: 519
},
end: {
line: 26,
column: 4,
character: 528
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector "#\\31span"',
start: {
line: 28,
column: 1,
character: 547
},
end: {
line: 28,
column: 9,
character: 555
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector "#\\31 span"',
start: {
line: 29,
column: 1,
character: 573
},
end: {
line: 29,
column: 10,
character: 582
}
}
]
});

@ -0,0 +1,21 @@
#\31\32\33 .svelte-xyz{ color: green; }
#\31 23.svelte-xyz { color: green; }
#line\a break.svelte-xyz { color: green; }
#line\a
break.svelte-xyz { color: green; }
#line\00000abreak.svelte-xyz { color: green; }
#line\00000a break.svelte-xyz { color: green; }
#line\00000a break.svelte-xyz { color: green; }
.a\1f642 b.svelte-xyz { color: green; }
.\61sdf.svelte-xyz { color: green; }
/* (unused) .\61 sdf { color: red; }*/
/* (unused) .\61
sdf { color: red; }*/
/* (unused) .\61
sdf { color: red; }*/
/* (unused) #\31span { color: red; }*/
/* (unused) #\31 span { color: red; }*/
#\31 .svelte-xyz span:where(.svelte-xyz) { color: green; }

@ -0,0 +1,7 @@
<div id="123" class="svelte-xyz"></div>
<div class="svelte-xyz" id="line
break"></div>
<div class="a🙂b svelte-xyz"></div>
<div class="asdf svelte-xyz"></div>
<div class="&#97;sdf svelte-xyz"></div>
<div id="1" class="svelte-xyz"><span class="svelte-xyz"></span></div>

@ -0,0 +1,31 @@
<div id="123"></div>
<div id="line
break"></div>
<div class="a🙂b"></div>
<div class="asdf"></div>
<div class="&#97;sdf"></div>
<div id="1"><span></span></div>
<style>
#\31\32\33 { color: green; }
#\31 23 { color: green; }
#line\a break { color: green; }
#line\a
break { color: green; }
#line\00000abreak { color: green; }
#line\00000a break { color: green; }
#line\00000a break { color: green; }
.a\1f642 b { color: green; }
.\61sdf { color: green; }
.\61 sdf { color: red; }
.\61
sdf { color: red; }
.\61
sdf { color: red; }
#\31span { color: red; }
#\31 span { color: red; }
#\31 span { color: green; }
</style>
Loading…
Cancel
Save