diff --git a/src/Microsoft.AspNetCore.Http.Abstractions/HostString.cs b/src/Microsoft.AspNetCore.Http.Abstractions/HostString.cs index e8c6ac3b35..4b4b24f7e5 100644 --- a/src/Microsoft.AspNetCore.Http.Abstractions/HostString.cs +++ b/src/Microsoft.AspNetCore.Http.Abstractions/HostString.cs @@ -4,6 +4,7 @@ using System; using System.Globalization; using Microsoft.AspNetCore.Http.Abstractions; +using Microsoft.AspNetCore.Http.Internal; namespace Microsoft.AspNetCore.Http { @@ -123,20 +124,29 @@ namespace Microsoft.AspNetCore.Http return string.Empty; } - string host, port; - - GetParts(out host, out port); - - if (host.IndexOf('[') == -1) - { - var mapping = new IdnMapping(); - host = mapping.GetAscii(host); + int i; + for (i = 0; i < _value.Length; ++i) + { + if (!HostStringHelper.IsSafeHostStringChar(_value[i])) + { + break; + } } - return string.IsNullOrEmpty(port) - ? host - : string.Concat(host, ":", port); - + if (i != _value.Length) + { + string host, port; + GetParts(out host, out port); + + var mapping = new IdnMapping(); + host = mapping.GetAscii(host); + + return string.IsNullOrEmpty(port) + ? host + : string.Concat(host, ":", port); + } + + return _value; } /// diff --git a/src/Microsoft.AspNetCore.Http.Abstractions/Internal/HostStringHelper.cs b/src/Microsoft.AspNetCore.Http.Abstractions/Internal/HostStringHelper.cs new file mode 100644 index 0000000000..f4cfac52af --- /dev/null +++ b/src/Microsoft.AspNetCore.Http.Abstractions/Internal/HostStringHelper.cs @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNetCore.Http.Internal +{ + internal class HostStringHelper + { + // Allowed Characters: + // A-Z, a-z, 0-9, ., + // -, %, [, ], : + // Above for IPV6 + private static bool[] SafeHostStringChars = { + false, false, false, false, false, false, false, false, // 0x00 - 0x07 + false, false, false, false, false, false, false, false, // 0x08 - 0x0F + false, false, false, false, false, false, false, false, // 0x10 - 0x17 + false, false, false, false, false, false, false, false, // 0x18 - 0x1F + false, false, false, false, false, true, false, false, // 0x20 - 0x27 + false, false, false, false, false, true, true, false, // 0x28 - 0x2F + true, true, true, true, true, true, true, true, // 0x30 - 0x37 + true, true, true, false, false, false, false, false, // 0x38 - 0x3F + false, true, true, true, true, true, true, true, // 0x40 - 0x47 + true, true, true, true, true, true, true, true, // 0x48 - 0x4F + true, true, true, true, true, true, true, true, // 0x50 - 0x57 + true, true, true, true, false, true, false, false, // 0x58 - 0x5F + false, true, true, true, true, true, true, true, // 0x60 - 0x67 + true, true, true, true, true, true, true, true, // 0x68 - 0x6F + true, true, true, true, true, true, true, true, // 0x70 - 0x77 + true, true, true, false, false, false, false, false, // 0x78 - 0x7F + }; + + public static bool IsSafeHostStringChar(char c) + { + return c < SafeHostStringChars.Length && SafeHostStringChars[c]; + } + } +}