Make UriTypeConverter better handle relative URIs (dotnet/corefx#42580)
authorEric StJohn <ericstj@microsoft.com>
Wed, 13 Nov 2019 22:46:42 +0000 (14:46 -0800)
committerSantiago Fernandez Madero <safern@microsoft.com>
Wed, 13 Nov 2019 22:46:42 +0000 (14:46 -0800)
We missed one case in handling relative URIs:
  ConvertTo(..., relativeUri, typeof(Uri))

Fix this, add tests, and share the UriKind calculation.

Commit migrated from https://github.com/dotnet/corefx/commit/136dba176f62308d701b992857d76ea790fd4631

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/UriTypeConverter.cs
src/libraries/System.ComponentModel.TypeConverter/tests/UriTypeConverterTests.cs

index d093dbf..5ce2648 100644 (file)
@@ -52,7 +52,7 @@ namespace System
 
             if (value is Uri uri)
             {
-                return new Uri(uri.OriginalString); // return new instance
+                return new Uri(uri.OriginalString, GetUriKind(uri));
             }
 
             throw GetConvertFromException(value);
@@ -75,7 +75,7 @@ namespace System
                 {
                     ConstructorInfo ctor = typeof(Uri).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(UriKind) }, null);
                     Debug.Assert(ctor != null, "Couldn't find constructor");
-                    return new InstanceDescriptor(ctor, new object[] { uri.OriginalString, uri.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative });
+                    return new InstanceDescriptor(ctor, new object[] { uri.OriginalString, GetUriKind(uri) });
                 }
 
                 if (destinationType == typeof(string))
@@ -85,7 +85,7 @@ namespace System
 
                 if (destinationType == typeof(Uri))
                 {
-                    return new Uri(uri.OriginalString, UriKind.RelativeOrAbsolute);
+                    return new Uri(uri.OriginalString, GetUriKind(uri));
                 }
             }
 
@@ -100,5 +100,7 @@ namespace System
             }
             return value is Uri;
         }
+
+        private static UriKind GetUriKind(Uri uri) => uri.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative;
     }
 }
index 3f44d39..ea390eb 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+using System;
 using System.ComponentModel.Design.Serialization;
 using System.Globalization;
 using Xunit;
@@ -39,9 +40,12 @@ namespace System.ComponentModel.Tests
         [Fact]
         public static void ConvertFrom_WithContext()
         {
-            ConvertFrom_WithContext(new object[2, 3]
+            ConvertFrom_WithContext(new object[5, 3]
                 {
                     {"http://www.Microsoft.com/", new Uri("http://www.Microsoft.com/"),  CultureInfo.InvariantCulture},
+                    {"/relative",  new Uri("/relative", UriKind.Relative),  CultureInfo.InvariantCulture},
+                    {new Uri("http://www.Microsoft.com/"), new Uri("http://www.Microsoft.com/"),  null},
+                    {new Uri("/relative", UriKind.Relative), new Uri("/relative", UriKind.Relative),  null},
                     {"mailto:?to=User2@Host2.com;cc=User3@Host3com", new Uri("mailto:?to=User2@Host2.com;cc=User3@Host3com"),  null}
                 },
                 UriTypeConverterTests.s_converter);
@@ -50,9 +54,10 @@ namespace System.ComponentModel.Tests
         [Fact]
         public static void ConvertTo_WithContext()
         {
-            ConvertTo_WithContext(new object[2, 3]
+            ConvertTo_WithContext(new object[3, 3]
                 {
                     {new Uri("http://www.Microsoft.com/"), "http://www.Microsoft.com/", CultureInfo.InvariantCulture},
+                    {new Uri("/relative", UriKind.Relative), "/relative", CultureInfo.InvariantCulture},
                     {new Uri("mailto:?to=User2@Host2.com;cc=User3@Host3com"), "mailto:?to=User2@Host2.com;cc=User3@Host3com",  null}
                 },
                 UriTypeConverterTests.s_converter);