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 <nbosch@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
This commit is contained in:
Lasse R.H. Nielsen
2024-11-15 15:00:21 +00:00
committed by Commit Queue
parent 25a9b7f5d2
commit 2e9058e9c9
2 changed files with 26 additions and 4 deletions
+4 -4
View File
@@ -2276,7 +2276,7 @@ final class _Uri implements _PlatformUri {
if ((char & 0xFC00) == 0xD800 && (index + 1) < end) {
int tail = host.codeUnitAt(index + 1);
if ((tail & 0xFC00) == 0xDC00) {
char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
char = 0x10000 + ((char & 0x3ff) << 10) + (tail & 0x3ff);
sourceLength = 2;
}
}
@@ -2354,7 +2354,7 @@ final class _Uri implements _PlatformUri {
if ((char & 0xFC00) == 0xD800 && (index + 1) < end) {
int tail = host.codeUnitAt(index + 1);
if ((tail & 0xFC00) == 0xDC00) {
char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
char = 0x10000 + ((char & 0x3ff) << 10) + (tail & 0x3ff);
sourceLength = 2;
}
}
@@ -2580,7 +2580,7 @@ final class _Uri implements _PlatformUri {
static String _escapeChar(int char) {
assert(char <= 0x10ffff); // It's a valid unicode code point.
List<int> codeUnits;
if (char < 0x80) {
if (char <= 0x7f) {
// ASCII, a single percent encoded sequence.
codeUnits = Uint8List(3);
codeUnits[0] = _PERCENT;
@@ -2692,7 +2692,7 @@ final class _Uri implements _PlatformUri {
if ((tail & 0xFC00) == 0xDC00) {
// Tail surrogate.
sourceLength = 2;
char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
char = 0x10000 + ((char & 0x3ff) << 10) + (tail & 0x3ff);
}
}
}
+22
View File
@@ -879,6 +879,28 @@ main() {
testReplace();
testPackageUris();
testBackslashes();
testNonBmpEncodingRegression();
}
void testNonBmpEncodingRegression() {
// Regression test for bug in encoding of some non-BMP characters
// in host names. The failing character has to be one that doesn't have
// the 0x10000 bit set in its code point, and which is not in the BMP.
const char = "\u{2003E}"; // CJK Unified Ideo­graph.
const echar = "%F0%A0%80%BE"; // UTF-8 encoding of page2Char, %-encoded.
var nonBmpUri =
Uri.parse("http://$char.example.com/x${char}x?y${char}y#z${char}z");
Expect.equals("http://$echar.example.com/x${echar}x?y${echar}y#z${echar}z",
nonBmpUri.toString());
Expect.equals("$echar.example.com", nonBmpUri.host);
Expect.equals("$char.example.com", Uri.decodeComponent(nonBmpUri.host));
Expect.equals("/x${echar}x", nonBmpUri.path);
Expect.equals("/x${char}x", Uri.decodeComponent(nonBmpUri.path));
Expect.equals("y${echar}y", nonBmpUri.query);
Expect.equals("y${char}y", Uri.decodeComponent(nonBmpUri.query));
Expect.equals("z${echar}z", nonBmpUri.fragment);
Expect.equals("z${char}z", Uri.decodeComponent(nonBmpUri.fragment));
}
String dump(Uri uri) {