Skip to content

Commit e13ff2f

Browse files
Fix: False Positive "Range out of order in character class" in Regular Expressions in Unicode Modes (#58982)
1 parent 369f2b0 commit e13ff2f

6 files changed

+203
-2
lines changed

src/compiler/scanner.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1640,7 +1640,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
16401640
const nextStart = pos;
16411641
let nextPos = pos + 2;
16421642
for (; nextPos < nextStart + 6; nextPos++) {
1643-
if (!isHexDigit(charCodeUnchecked(pos))) {
1643+
if (!isHexDigit(charCodeUnchecked(nextPos))) {
16441644
// leave the error to the next call
16451645
return escapedValueString;
16461646
}
@@ -3552,7 +3552,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
35523552
}
35533553

35543554
function scanSourceCharacter(): string {
3555-
const size = anyUnicodeMode ? charSize(charCodeChecked(pos)) : 1;
3555+
const size = anyUnicodeMode ? charSize(codePointChecked(pos)) : 1;
35563556
pos += size;
35573557
return size > 0 ? text.substring(pos - size, pos) : "";
35583558
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
regularExpressionCharacterClassRangeOrder.ts(7,5): error TS1517: Range out of order in character class.
2+
regularExpressionCharacterClassRangeOrder.ts(7,12): error TS1517: Range out of order in character class.
3+
regularExpressionCharacterClassRangeOrder.ts(8,11): error TS1517: Range out of order in character class.
4+
regularExpressionCharacterClassRangeOrder.ts(9,11): error TS1517: Range out of order in character class.
5+
regularExpressionCharacterClassRangeOrder.ts(11,6): error TS1125: Hexadecimal digit expected.
6+
regularExpressionCharacterClassRangeOrder.ts(11,16): error TS1125: Hexadecimal digit expected.
7+
regularExpressionCharacterClassRangeOrder.ts(11,27): error TS1125: Hexadecimal digit expected.
8+
regularExpressionCharacterClassRangeOrder.ts(11,37): error TS1125: Hexadecimal digit expected.
9+
regularExpressionCharacterClassRangeOrder.ts(12,25): error TS1517: Range out of order in character class.
10+
regularExpressionCharacterClassRangeOrder.ts(13,25): error TS1517: Range out of order in character class.
11+
regularExpressionCharacterClassRangeOrder.ts(15,10): error TS1517: Range out of order in character class.
12+
regularExpressionCharacterClassRangeOrder.ts(15,37): error TS1517: Range out of order in character class.
13+
regularExpressionCharacterClassRangeOrder.ts(16,31): error TS1517: Range out of order in character class.
14+
regularExpressionCharacterClassRangeOrder.ts(17,31): error TS1517: Range out of order in character class.
15+
16+
17+
==== regularExpressionCharacterClassRangeOrder.ts (14 errors) ====
18+
// The characters in the following regular expressions are ASCII-lookalike characters found in Unicode, including:
19+
// - 𝘈 (U+1D608 Mathematical Sans-Serif Italic Capital A)
20+
// - 𝘡 (U+1D621 Mathematical Sans-Serif Italic Capital Z)
21+
//
22+
// See https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
23+
const regexes: RegExp[] = [
24+
/[𝘈-𝘡][𝘡-𝘈]/,
25+
~~~
26+
!!! error TS1517: Range out of order in character class.
27+
~~~
28+
!!! error TS1517: Range out of order in character class.
29+
/[𝘈-𝘡][𝘡-𝘈]/u,
30+
~~~~~
31+
!!! error TS1517: Range out of order in character class.
32+
/[𝘈-𝘡][𝘡-𝘈]/v,
33+
~~~~~
34+
!!! error TS1517: Range out of order in character class.
35+
36+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/,
37+
38+
!!! error TS1125: Hexadecimal digit expected.
39+
40+
!!! error TS1125: Hexadecimal digit expected.
41+
42+
!!! error TS1125: Hexadecimal digit expected.
43+
44+
!!! error TS1125: Hexadecimal digit expected.
45+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/u,
46+
~~~~~~~~~~~~~~~~~~~
47+
!!! error TS1517: Range out of order in character class.
48+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/v,
49+
~~~~~~~~~~~~~~~~~~~
50+
!!! error TS1517: Range out of order in character class.
51+
52+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/,
53+
~~~~~~~~~~~~~
54+
!!! error TS1517: Range out of order in character class.
55+
~~~~~~~~~~~~~
56+
!!! error TS1517: Range out of order in character class.
57+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/u,
58+
~~~~~~~~~~~~~~~~~~~~~~~~~
59+
!!! error TS1517: Range out of order in character class.
60+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/v,
61+
~~~~~~~~~~~~~~~~~~~~~~~~~
62+
!!! error TS1517: Range out of order in character class.
63+
];
64+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//// [tests/cases/compiler/regularExpressionCharacterClassRangeOrder.ts] ////
2+
3+
//// [regularExpressionCharacterClassRangeOrder.ts]
4+
// The characters in the following regular expressions are ASCII-lookalike characters found in Unicode, including:
5+
// - 𝘈 (U+1D608 Mathematical Sans-Serif Italic Capital A)
6+
// - 𝘡 (U+1D621 Mathematical Sans-Serif Italic Capital Z)
7+
//
8+
// See https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
9+
const regexes: RegExp[] = [
10+
/[𝘈-𝘡][𝘡-𝘈]/,
11+
/[𝘈-𝘡][𝘡-𝘈]/u,
12+
/[𝘈-𝘡][𝘡-𝘈]/v,
13+
14+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/,
15+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/u,
16+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/v,
17+
18+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/,
19+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/u,
20+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/v,
21+
];
22+
23+
24+
//// [regularExpressionCharacterClassRangeOrder.js]
25+
// The characters in the following regular expressions are ASCII-lookalike characters found in Unicode, including:
26+
// - 𝘈 (U+1D608 Mathematical Sans-Serif Italic Capital A)
27+
// - 𝘡 (U+1D621 Mathematical Sans-Serif Italic Capital Z)
28+
//
29+
// See https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
30+
const regexes = [
31+
/[𝘈-𝘡][𝘡-𝘈]/,
32+
/[𝘈-𝘡][𝘡-𝘈]/u,
33+
/[𝘈-𝘡][𝘡-𝘈]/v,
34+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/,
35+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/u,
36+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/v,
37+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/,
38+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/u,
39+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/v,
40+
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//// [tests/cases/compiler/regularExpressionCharacterClassRangeOrder.ts] ////
2+
3+
=== regularExpressionCharacterClassRangeOrder.ts ===
4+
// The characters in the following regular expressions are ASCII-lookalike characters found in Unicode, including:
5+
// - 𝘈 (U+1D608 Mathematical Sans-Serif Italic Capital A)
6+
// - 𝘡 (U+1D621 Mathematical Sans-Serif Italic Capital Z)
7+
//
8+
// See https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
9+
const regexes: RegExp[] = [
10+
>regexes : Symbol(regexes, Decl(regularExpressionCharacterClassRangeOrder.ts, 5, 5))
11+
>RegExp : Symbol(RegExp, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.regexp.d.ts, --, --) ... and 3 more)
12+
13+
/[𝘈-𝘡][𝘡-𝘈]/,
14+
/[𝘈-𝘡][𝘡-𝘈]/u,
15+
/[𝘈-𝘡][𝘡-𝘈]/v,
16+
17+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/,
18+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/u,
19+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/v,
20+
21+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/,
22+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/u,
23+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/v,
24+
];
25+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//// [tests/cases/compiler/regularExpressionCharacterClassRangeOrder.ts] ////
2+
3+
=== regularExpressionCharacterClassRangeOrder.ts ===
4+
// The characters in the following regular expressions are ASCII-lookalike characters found in Unicode, including:
5+
// - 𝘈 (U+1D608 Mathematical Sans-Serif Italic Capital A)
6+
// - 𝘡 (U+1D621 Mathematical Sans-Serif Italic Capital Z)
7+
//
8+
// See https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
9+
const regexes: RegExp[] = [
10+
>regexes : RegExp[]
11+
> : ^^^^^^^^
12+
>[ /[𝘈-𝘡][𝘡-𝘈]/, /[𝘈-𝘡][𝘡-𝘈]/u, /[𝘈-𝘡][𝘡-𝘈]/v, /[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/, /[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/u, /[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/v, /[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/, /[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/u, /[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/v,] : RegExp[]
13+
> : ^^^^^^^^
14+
15+
/[𝘈-𝘡][𝘡-𝘈]/,
16+
>/[𝘈-𝘡][𝘡-𝘈]/ : RegExp
17+
> : ^^^^^^
18+
19+
/[𝘈-𝘡][𝘡-𝘈]/u,
20+
>/[𝘈-𝘡][𝘡-𝘈]/u : RegExp
21+
> : ^^^^^^
22+
23+
/[𝘈-𝘡][𝘡-𝘈]/v,
24+
>/[𝘈-𝘡][𝘡-𝘈]/v : RegExp
25+
> : ^^^^^^
26+
27+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/,
28+
>/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/ : RegExp
29+
> : ^^^^^^
30+
31+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/u,
32+
>/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/u : RegExp
33+
> : ^^^^^^
34+
35+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/v,
36+
>/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/v : RegExp
37+
> : ^^^^^^
38+
39+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/,
40+
>/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/ : RegExp
41+
> : ^^^^^^
42+
43+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/u,
44+
>/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/u : RegExp
45+
> : ^^^^^^
46+
47+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/v,
48+
>/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/v : RegExp
49+
> : ^^^^^^
50+
51+
];
52+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @target: esnext
2+
3+
// The characters in the following regular expressions are ASCII-lookalike characters found in Unicode, including:
4+
// - 𝘈 (U+1D608 Mathematical Sans-Serif Italic Capital A)
5+
// - 𝘡 (U+1D621 Mathematical Sans-Serif Italic Capital Z)
6+
//
7+
// See https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
8+
const regexes: RegExp[] = [
9+
/[𝘈-𝘡][𝘡-𝘈]/,
10+
/[𝘈-𝘡][𝘡-𝘈]/u,
11+
/[𝘈-𝘡][𝘡-𝘈]/v,
12+
13+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/,
14+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/u,
15+
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/v,
16+
17+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/,
18+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/u,
19+
/[\uD835\uDE08-\uD835\uDE21][\uD835\uDE21-\uD835\uDE08]/v,
20+
];

0 commit comments

Comments
 (0)