From 436f155963bbf8f1b44bb7ad51119b6d44914a21 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Wed, 26 Aug 2020 15:08:29 +0200 Subject: [PATCH] Reset all Uri fields when reusing an instance (#41324) * Reset all Uri fields when reusing an instance * Test combined Uri's AbsoluteUri --- .../System.Private.Uri/src/System/Uri.cs | 2 ++ .../System.Private.Uri/src/System/UriExt.cs | 2 ++ .../tests/FunctionalTests/UriTests.cs | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index 1ed13695b645d..754ac60bf5b87 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -504,6 +504,7 @@ private void CreateUri(Uri baseUri, string? relativeUri, bool dontEscape) _flags = Flags.Zero; _info = null!; _syntax = null!; + _originalUnicodeString = null!; // If not resolved, we reparse modified Uri string and populate Uri internal data. CreateThis(relativeUri, dontEscape, UriKind.Absolute); } @@ -550,6 +551,7 @@ public Uri(Uri baseUri, Uri relativeUri) _flags = Flags.Zero; _info = null!; _syntax = null!; + _originalUnicodeString = null!; CreateThis(newUriString, dontEscape, UriKind.Absolute); DebugSetLeftCtor(); } diff --git a/src/libraries/System.Private.Uri/src/System/UriExt.cs b/src/libraries/System.Private.Uri/src/System/UriExt.cs index 3b4504ac72b26..ff74af22a9bd9 100644 --- a/src/libraries/System.Private.Uri/src/System/UriExt.cs +++ b/src/libraries/System.Private.Uri/src/System/UriExt.cs @@ -26,6 +26,8 @@ private void CreateThis(string? uri, bool dontEscape, UriKind uriKind) _string = uri ?? string.Empty; + Debug.Assert(_originalUnicodeString is null && _info is null && _syntax is null && _flags == Flags.Zero); + if (dontEscape) _flags |= Flags.UserEscaped; diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs index 5dea3b30e95e9..2b2222f315d82 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs @@ -709,6 +709,25 @@ public static void Uri_EmptyPort_UsesDefaultPort() Assert.Equal(80, u.Port); } + [Fact] + public static void Uri_CombineUsesNewUriString() + { + // Tests that internal Uri fields were properly reset during a Combine operation + // Otherwise, the wrong Uri string would be used if the relative Uri contains non-ascii characters + // This will only affect parsers without the IriParsing flag - only custom parsers + UriParser.Register(new GenericUriParser(GenericUriParserOptions.GenericAuthority), "combine-scheme", -1); + + const string BaseUriString = "combine-scheme://foo"; + const string RelativeUriString = "/relative/uri/with/non/ascii/\u00FC"; + const string Combined = BaseUriString + "/relative/uri/with/non/ascii/%C3%BC"; + + var baseUri = new Uri(BaseUriString, UriKind.Absolute); + var relativeUri = new Uri(RelativeUriString, UriKind.Relative); + + Assert.Equal(Combined, new Uri(baseUri, relativeUri).AbsoluteUri); + Assert.Equal(Combined, new Uri(baseUri, RelativeUriString).AbsoluteUri); + } + [Fact] public static void Uri_CachesIdnHost() {