Skip to content

Commit 2e9058e

Browse files
lrhnCommit Queue
authored andcommitted
Fix bug in encoding of non-BMP characters of URI host names.
Encoded the incorrect code point if the character is was on an even page. (Which excludes emojis, so likely nobody noticed.) CoreLibraryReviewExempt: Localized bugfix. Change-Id: I4dcb04d0c8ea2cb85af4a43e1fbfa8c27e5b00f9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/395241 Reviewed-by: Nate Bosch <[email protected]> Commit-Queue: Lasse Nielsen <[email protected]>
1 parent 25a9b7f commit 2e9058e

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

sdk/lib/core/uri.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,7 +2276,7 @@ final class _Uri implements _PlatformUri {
22762276
if ((char & 0xFC00) == 0xD800 && (index + 1) < end) {
22772277
int tail = host.codeUnitAt(index + 1);
22782278
if ((tail & 0xFC00) == 0xDC00) {
2279-
char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
2279+
char = 0x10000 + ((char & 0x3ff) << 10) + (tail & 0x3ff);
22802280
sourceLength = 2;
22812281
}
22822282
}
@@ -2354,7 +2354,7 @@ final class _Uri implements _PlatformUri {
23542354
if ((char & 0xFC00) == 0xD800 && (index + 1) < end) {
23552355
int tail = host.codeUnitAt(index + 1);
23562356
if ((tail & 0xFC00) == 0xDC00) {
2357-
char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
2357+
char = 0x10000 + ((char & 0x3ff) << 10) + (tail & 0x3ff);
23582358
sourceLength = 2;
23592359
}
23602360
}
@@ -2580,7 +2580,7 @@ final class _Uri implements _PlatformUri {
25802580
static String _escapeChar(int char) {
25812581
assert(char <= 0x10ffff); // It's a valid unicode code point.
25822582
List<int> codeUnits;
2583-
if (char < 0x80) {
2583+
if (char <= 0x7f) {
25842584
// ASCII, a single percent encoded sequence.
25852585
codeUnits = Uint8List(3);
25862586
codeUnits[0] = _PERCENT;
@@ -2692,7 +2692,7 @@ final class _Uri implements _PlatformUri {
26922692
if ((tail & 0xFC00) == 0xDC00) {
26932693
// Tail surrogate.
26942694
sourceLength = 2;
2695-
char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
2695+
char = 0x10000 + ((char & 0x3ff) << 10) + (tail & 0x3ff);
26962696
}
26972697
}
26982698
}

tests/corelib/uri_test.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,28 @@ main() {
879879
testReplace();
880880
testPackageUris();
881881
testBackslashes();
882+
883+
testNonBmpEncodingRegression();
884+
}
885+
886+
void testNonBmpEncodingRegression() {
887+
// Regression test for bug in encoding of some non-BMP characters
888+
// in host names. The failing character has to be one that doesn't have
889+
// the 0x10000 bit set in its code point, and which is not in the BMP.
890+
const char = "\u{2003E}"; // CJK Unified Ideo­graph.
891+
const echar = "%F0%A0%80%BE"; // UTF-8 encoding of page2Char, %-encoded.
892+
var nonBmpUri =
893+
Uri.parse("http://$char.example.com/x${char}x?y${char}y#z${char}z");
894+
Expect.equals("http://$echar.example.com/x${echar}x?y${echar}y#z${echar}z",
895+
nonBmpUri.toString());
896+
Expect.equals("$echar.example.com", nonBmpUri.host);
897+
Expect.equals("$char.example.com", Uri.decodeComponent(nonBmpUri.host));
898+
Expect.equals("/x${echar}x", nonBmpUri.path);
899+
Expect.equals("/x${char}x", Uri.decodeComponent(nonBmpUri.path));
900+
Expect.equals("y${echar}y", nonBmpUri.query);
901+
Expect.equals("y${char}y", Uri.decodeComponent(nonBmpUri.query));
902+
Expect.equals("z${echar}z", nonBmpUri.fragment);
903+
Expect.equals("z${char}z", Uri.decodeComponent(nonBmpUri.fragment));
882904
}
883905

884906
String dump(Uri uri) {

0 commit comments

Comments
 (0)