diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index 6e3777358beb99..caf4b4e1902b94 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -2235,6 +2235,10 @@ private unsafe ParsingError PrivateParseMinimal() if (newHost is not null) { _string = newHost; + // newHost contains everything from the start through the end of the authority + // with bidi characters removed. idx should point to the position right after + // the authority in the new string, which is simply newHost.Length. + idx = newHost.Length; } } diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs index bf1a31d6c7927d..afe6e83019e113 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs @@ -1001,5 +1001,21 @@ static void Test(string uriString) Assert.Throws(() => uri.AbsoluteUri); } } + + [Theory] + [InlineData("/\\//")] + [InlineData("\\/\u200e")] + [InlineData("/\\\\-\u0100\r")] + [InlineData("\\\\\\\\\\")] + [InlineData("\\\\\u200E")] + [InlineData("\\\\\u200E:1234")] + [InlineData("\\\\\u200E//")] + [InlineData("\\\\\u200E//ab")] + public static void InvalidUriWithBidiControlCharacters_ThrowsUriFormatException(string uriString) + { + // These URIs should throw UriFormatException, not IndexOutOfRangeException + // Issue: https://github.com/dotnet/runtime/issues/18640 + Assert.Throws(() => new Uri(uriString, UriKind.Absolute)); + } } }