From d16afcea4f4ecddd49d53bcb569ae3fa9e500882 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Fri, 13 Mar 2020 16:30:00 +0100 Subject: [PATCH] Replace ushort usage with int (#32694) * Replace pointless ushort usage with int * Revert extracting name[i] to a local * Use int instead of byte in IPv4 ParseCanonical --- .../src/System/Net/IPv4AddressHelper.Common.cs | 7 +- .../src/System/DomainNameHelper.cs | 8 +- .../System.Private.Uri/src/System/UncNameHelper.cs | 6 +- src/libraries/System.Private.Uri/src/System/Uri.cs | 269 ++++++++++----------- .../System.Private.Uri/src/System/UriExt.cs | 12 +- .../System.Private.Uri/src/System/UriHelper.cs | 4 +- 6 files changed, 148 insertions(+), 158 deletions(-) diff --git a/src/libraries/Common/src/System/Net/IPv4AddressHelper.Common.cs b/src/libraries/Common/src/System/Net/IPv4AddressHelper.Common.cs index e2815bf..fc390e5 100644 --- a/src/libraries/Common/src/System/Net/IPv4AddressHelper.Common.cs +++ b/src/libraries/Common/src/System/Net/IPv4AddressHelper.Common.cs @@ -86,14 +86,13 @@ namespace System { for (int i = 0; i < NumberOfLabels; ++i) { - - byte b = 0; + int b = 0; char ch; for (; (start < end) && (ch = name[start]) != '.' && ch != ':'; ++start) { - b = (byte)(b * 10 + (byte)(ch - '0')); + b = (b * 10) + ch - '0'; } - numbers[i] = b; + numbers[i] = (byte)b; ++start; } return numbers[0] == 127; diff --git a/src/libraries/System.Private.Uri/src/System/DomainNameHelper.cs b/src/libraries/System.Private.Uri/src/System/DomainNameHelper.cs index eddf579..c8bcf23 100644 --- a/src/libraries/System.Private.Uri/src/System/DomainNameHelper.cs +++ b/src/libraries/System.Private.Uri/src/System/DomainNameHelper.cs @@ -67,7 +67,7 @@ namespace System // MUST NOT be used unless all input indexes are verified and trusted. // - internal static unsafe bool IsValid(char* name, ushort pos, ref int returnedEnd, ref bool notCanonical, bool notImplicitFile) + internal static unsafe bool IsValid(char* name, int pos, ref int returnedEnd, ref bool notCanonical, bool notImplicitFile) { char* curPos = name + pos; char* newPos = curPos; @@ -124,7 +124,7 @@ namespace System ++curPos; } while (curPos < end); - returnedEnd = (ushort)(end - name); + returnedEnd = (int)(end - name); return true; } @@ -133,7 +133,7 @@ namespace System // There are pretty much no restrictions and we effectively return the end of the // domain name. // - internal static unsafe bool IsValidByIri(char* name, ushort pos, ref int returnedEnd, ref bool notCanonical, bool notImplicitFile) + internal static unsafe bool IsValidByIri(char* name, int pos, ref int returnedEnd, ref bool notCanonical, bool notImplicitFile) { char* curPos = name + pos; char* newPos = curPos; @@ -200,7 +200,7 @@ namespace System ++curPos; } while (curPos < end); - returnedEnd = (ushort)(end - name); + returnedEnd = (int)(end - name); return true; } diff --git a/src/libraries/System.Private.Uri/src/System/UncNameHelper.cs b/src/libraries/System.Private.Uri/src/System/UncNameHelper.cs index 26cec9d..0b643b8 100644 --- a/src/libraries/System.Private.Uri/src/System/UncNameHelper.cs +++ b/src/libraries/System.Private.Uri/src/System/UncNameHelper.cs @@ -49,9 +49,9 @@ namespace System // // Assumption is the caller will check on the resulting name length // Remarks: MUST NOT be used unless all input indexes are verified and trusted. - internal static unsafe bool IsValid(char* name, ushort start, ref int returnedEnd, bool notImplicitFile) + internal static unsafe bool IsValid(char* name, int start, ref int returnedEnd, bool notImplicitFile) { - ushort end = (ushort)returnedEnd; + int end = returnedEnd; if (start == end) return false; @@ -59,7 +59,7 @@ namespace System // First segment could consist of only '_' or '-' but it cannot be all digits or empty // bool validShortName = false; - ushort i = start; + int i = start; for (; i < end; ++i) { if (name[i] == '/' || name[i] == '\\' || (notImplicitFile && (name[i] == ':' || name[i] == '?' || name[i] == '#'))) diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index e8d9363..c49ef8f 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -222,7 +222,7 @@ namespace System _flags = Flags.UserDrivenParsing | (_flags & Flags.UserEscaped); } - private ushort SecuredPathIndex + private int SecuredPathIndex { get { @@ -231,9 +231,9 @@ namespace System if (IsDosPath) { char ch = _string[_info.Offset.Path]; - return (ushort)((ch == '/' || ch == '\\') ? 3 : 2); + return (ch == '/' || ch == '\\') ? 3 : 2; } - return (ushort)0; + return 0; } } @@ -1706,16 +1706,16 @@ namespace System // Note there could be explicit ports specified that would invalidate path offsets if (InFact(Flags.CanonicalDnsHost) && obj.InFact(Flags.CanonicalDnsHost)) { - ushort i1 = _info.Offset.Host; - ushort end1 = _info.Offset.Path; + int i1 = _info.Offset.Host; + int end1 = _info.Offset.Path; - ushort i2 = obj._info.Offset.Host; - ushort end2 = obj._info.Offset.Path; + int i2 = obj._info.Offset.Host; + int end2 = obj._info.Offset.Path; string str = obj._string; //Taking the shortest part if (end1 - i1 > end2 - i2) { - end1 = (ushort)(i1 + end2 - i2); + end1 = i1 + end2 - i2; } // compare and break on ':' if found while (i1 < end1) @@ -1905,7 +1905,7 @@ namespace System fixed (char* pUriString = uriString) { ParsingError err = ParsingError.None; - ushort idx = ParseSchemeCheckImplicitFile(pUriString, (ushort)length, ref err, ref flags, ref syntax); + int idx = ParseSchemeCheckImplicitFile(pUriString, length, ref err, ref flags, ref syntax); if (err != ParsingError.None) return err; @@ -1945,8 +1945,8 @@ namespace System // private unsafe ParsingError PrivateParseMinimal() { - ushort idx = (ushort)(_flags & Flags.IndexMask); - ushort length = (ushort)_string.Length; + int idx = (int)(_flags & Flags.IndexMask); + int length = _string.Length; string? newHost = null; // stores newly parsed host when original strings are being switched // Means a custom UriParser did call "base" InitializeAndValidate() @@ -1985,7 +1985,7 @@ namespace System && NotAny(Flags.ImplicitFile) && (idx + 1 < length)) { char c; - ushort i = idx; + int i = idx; // V1 Compat: Allow _compression_ of > 3 slashes only for File scheme. // This will skip all slashes and if their number is 2+ it sets the AuthorityFound flag @@ -2025,7 +2025,7 @@ namespace System if (i != idx && i - idx != 2) { //This will remember that DosPath is rooted - idx = (ushort)(i - 1); + idx = i - 1; } else { @@ -2135,7 +2135,7 @@ namespace System if (err != ParsingError.None) return err; - if (idx < (ushort)length) + if (idx < length) { char hostTerminator = pUriString[idx]; @@ -2161,23 +2161,20 @@ namespace System } if (_iriParsing) - PrivateParseMinimalIri(newHost, idx); - - return ParsingError.None; - } - - private void PrivateParseMinimalIri(string? newHost, ushort idx) - { - // we have a new host! - if (newHost != null) - _string = newHost; - - // Indicate to createuriinfo that offset is in m_originalUnicodeString - if (_iriParsing && ((_flags & Flags.HasUnicode) != 0)) { - // offset in Flags.IndexMask refers to m_originalUnicodeString - _flags |= Flags.UseOrigUncdStrOffset; + // we have a new host! + if (newHost != null) + _string = newHost; + + // Indicate to createuriinfo that offset is in m_originalUnicodeString + if (_iriParsing && ((_flags & Flags.HasUnicode) != 0)) + { + // offset in Flags.IndexMask refers to m_originalUnicodeString + _flags |= Flags.UseOrigUncdStrOffset; + } } + + return ParsingError.None; } // @@ -2196,14 +2193,14 @@ namespace System if (UserDrivenParsing) goto Done; - ushort idx; + int idx; bool notCanonicalScheme = false; // The m_String may have leading spaces, figure that out // plus it will set idx value for next steps if ((cF & Flags.ImplicitFile) != 0) { - idx = (ushort)0; + idx = 0; while (UriHelper.IsLWS(_string[idx])) { ++idx; @@ -2215,7 +2212,8 @@ namespace System // For implicit file AND Unc only idx += 2; //skip any other slashes (compatibility with V1.0 parser) - while (idx < (ushort)(cF & Flags.IndexMask) && (_string[idx] == '/' || _string[idx] == '\\')) + int end = (int)(cF & Flags.IndexMask); + while (idx < end && (_string[idx] == '/' || _string[idx] == '\\')) { ++idx; } @@ -2224,7 +2222,7 @@ namespace System else { // This is NOT an ImplicitFile uri - idx = (ushort)_syntax.SchemeName.Length; + idx = _syntax.SchemeName.Length; while (_string[idx++] != ':') { @@ -2241,7 +2239,8 @@ namespace System { // Skip slashes if it was allowed during ctor time // NB: Today this is only allowed if a Unc or DosPath was found after the scheme - while (idx < (ushort)(cF & Flags.IndexMask) && (_string[idx] == '/' || _string[idx] == '\\')) + int end = (int)(cF & Flags.IndexMask); + while (idx < end && (_string[idx] == '/' || _string[idx] == '\\')) { notCanonicalScheme = true; ++idx; @@ -2271,12 +2270,12 @@ namespace System goto Done; } - info.Offset.User = idx; + info.Offset.User = (ushort)idx; //Basic Host Type does not have userinfo and port if (HostType == Flags.BasicHostType) { - info.Offset.Host = idx; + info.Offset.Host = (ushort)idx; info.Offset.Path = (ushort)(cF & Flags.IndexMask); cF &= ~Flags.IndexMask; goto Done; @@ -2290,16 +2289,16 @@ namespace System ++idx; } ++idx; - info.Offset.Host = idx; + info.Offset.Host = (ushort)idx; } else { - info.Offset.Host = idx; + info.Offset.Host = (ushort)idx; } //Now reload the end of the parsed host - idx = (ushort)(cF & Flags.IndexMask); + idx = (int)(cF & Flags.IndexMask); //From now on we do not need IndexMask bits, and reuse the space for X_NotCanonical flags //clear them now @@ -2312,7 +2311,7 @@ namespace System } //Guessing this is a path start - info.Offset.Path = idx; + info.Offset.Path = (ushort)idx; // parse Port if any. The new spec allows a port after ':' to be empty (assuming default?) bool notEmpty = false; @@ -2339,8 +2338,8 @@ namespace System //Check on some non-canonical cases http://host:0324/, http://host:03, http://host:0, etc if (++idx < info.Offset.End) { - port = unchecked((ushort)(userString[idx] - '0')); - if (port <= unchecked((ushort)('9' - '0'))) + port = userString[idx] - '0'; + if ((uint)port <= ('9' - '0')) { notEmpty = true; if (port == 0) @@ -2349,8 +2348,8 @@ namespace System } for (++idx; idx < info.Offset.End; ++idx) { - ushort val = unchecked((ushort)((ushort)userString[idx] - (ushort)'0')); - if (val > unchecked((ushort)('9' - '0'))) + int val = userString[idx] - '0'; + if ((uint)val > ('9' - '0')) { break; } @@ -2358,7 +2357,7 @@ namespace System } } } - if (notEmpty && info.Offset.PortValue != (ushort)port) + if (notEmpty && info.Offset.PortValue != port) { info.Offset.PortValue = (ushort)port; cF |= Flags.NotDefaultPort; @@ -2418,11 +2417,11 @@ namespace System // An Authority may need escaping except when it's an inet server address if (HostType == Flags.BasicHostType) { - ushort idx = 0; + int idx = 0; Check result; fixed (char* pHost = host) { - result = CheckCanonical(pHost, ref idx, (ushort)host.Length, c_DummyChar); + result = CheckCanonical(pHost, ref idx, host.Length, c_DummyChar); } if ((result & Check.DisplayCanonical) == 0) @@ -2485,7 +2484,7 @@ namespace System } } - private static string CreateHostStringHelper(string str, ushort idx, ushort end, ref Flags flags, ref string? scopeId) + private static string CreateHostStringHelper(string str, int idx, int end, ref Flags flags, ref string? scopeId) { bool loopback = false; string host; @@ -2565,8 +2564,8 @@ namespace System fixed (char* pHost = host) { string? newHost = null; - if (CheckAuthorityHelper(pHost, 0, (ushort)host.Length, ref err, ref flags, _syntax, ref newHost) != - (ushort)host.Length) + if (CheckAuthorityHelper(pHost, 0, host.Length, ref err, ref flags, _syntax, ref newHost) != + host.Length) { // We cannot parse the entire host string flags &= ~Flags.HostTypeMask; @@ -2581,7 +2580,7 @@ namespace System } else { - host = CreateHostStringHelper(host, 0, (ushort)host.Length, ref flags, ref _info.ScopeId); + host = CreateHostStringHelper(host, 0, host.Length, ref flags, ref _info.ScopeId); for (int i = 0; i < host.Length; ++i) { if ((_info.Offset.Host + i) >= _info.Offset.End || host[i] != _string[_info.Offset.Host + i]) @@ -2851,7 +2850,7 @@ namespace System //take it from m_String if (InFact(Flags.NotDefaultPort)) { - ushort start = _info.Offset.Path; + int start = _info.Offset.Path; while (_string[--start] != ':') { ; @@ -2878,7 +2877,7 @@ namespace System } } - ushort delimiterAwareIndex; + int delimiterAwareIndex; //Path if ((parts & UriComponents.Path) != 0) @@ -2903,7 +2902,7 @@ namespace System //Query (possibly strip the '?' delimiter) if ((parts & UriComponents.Query) != 0 && _info.Offset.Query < _info.Offset.Fragment) { - delimiterAwareIndex = (ushort)(_info.Offset.Query + 1); + delimiterAwareIndex = (_info.Offset.Query + 1); if (parts != UriComponents.Query) chars[count++] = '?'; //see Fragment+1 below @@ -2961,7 +2960,7 @@ namespace System //Fragment (possibly strip the '#' delimiter) if ((parts & UriComponents.Fragment) != 0 && _info.Offset.Fragment < _info.Offset.End) { - delimiterAwareIndex = (ushort)(_info.Offset.Fragment + 1); + delimiterAwareIndex = _info.Offset.Fragment + 1; if (parts != UriComponents.Fragment) chars[count++] = '#'; //see Fragment+1 below @@ -3023,7 +3022,7 @@ namespace System // private string? GetUriPartsFromUserString(UriComponents uriParts) { - ushort delimiterAwareIdx; + int delimiterAwareIdx; switch (uriParts & ~UriComponents.KeepDelimiter) { @@ -3089,7 +3088,7 @@ namespace System // KeepDelimiter makes no sense for this component case UriComponents.Host: - ushort idx = _info.Offset.Path; + int idx = _info.Offset.Path; if (InFact(Flags.NotDefaultPort | Flags.PortNotCanonical)) { //Means we do have ':' after the host @@ -3104,7 +3103,7 @@ namespace System // Strip the leading '/' for a hierarchical URI if no delimiter was requested if (uriParts == UriComponents.Path && InFact(Flags.AuthorityFound) && _info.Offset.End > _info.Offset.Path && _string[_info.Offset.Path] == '/') - delimiterAwareIdx = (ushort)(_info.Offset.Path + 1); + delimiterAwareIdx = _info.Offset.Path + 1; else delimiterAwareIdx = _info.Offset.Path; @@ -3117,7 +3116,7 @@ namespace System case UriComponents.Query: // Strip the '?' if no delimiter was requested if (uriParts == UriComponents.Query) - delimiterAwareIdx = (ushort)(_info.Offset.Query + 1); + delimiterAwareIdx = _info.Offset.Query + 1; else delimiterAwareIdx = _info.Offset.Query; @@ -3129,7 +3128,7 @@ namespace System case UriComponents.Fragment: // Strip the '#' if no delimiter was requested if (uriParts == UriComponents.Fragment) - delimiterAwareIdx = (ushort)(_info.Offset.Fragment + 1); + delimiterAwareIdx = _info.Offset.Fragment + 1; else delimiterAwareIdx = _info.Offset.Fragment; @@ -3174,7 +3173,7 @@ namespace System return string.Empty; if (uriParts == UriComponents.UserInfo) - delimiterAwareIdx = (ushort)(_info.Offset.Host - 1); + delimiterAwareIdx = _info.Offset.Host - 1; else delimiterAwareIdx = _info.Offset.Host; @@ -3189,10 +3188,10 @@ namespace System } // Cut trailing spaces - private void GetLengthWithoutTrailingSpaces(string str, ref ushort length, int idx) + private void GetLengthWithoutTrailingSpaces(string str, ref int length, int idx) { // to avoid dereferencing ref length parameter for every update - ushort local = length; + int local = length; while (local > idx && UriHelper.IsLWS(str[local - 1])) --local; length = local; } @@ -3219,9 +3218,9 @@ namespace System // Do we have to continue building Iri'zed string from original string bool buildIriStringFromPath = _iriParsing && ((_flags & Flags.HasUnicode) != 0) && ((_flags & Flags.RestUnicodeNormalized) == 0); - ushort origIdx; // stores index to switched original string - ushort idx = _info.Offset.Scheme; - ushort length = (ushort)_string.Length; + int origIdx; // stores index to switched original string + int idx = _info.Offset.Scheme; + int length = _string.Length; Check result = Check.None; UriSyntaxFlags syntaxFlags = _syntax.Flags; @@ -3237,11 +3236,11 @@ namespace System } else { - ushort i = 0; - ushort syntaxLength = (ushort)_syntax.SchemeName.Length; - for (; i < syntaxLength; ++i) + int i; + string schemeName = _syntax.SchemeName; + for (i = 0; i < schemeName.Length; ++i) { - if (_syntax.SchemeName[i] != str[idx + i]) + if (schemeName[i] != str[idx + i]) cF |= Flags.SchemeNotCanonical; } // For an authority Uri only // after the scheme would be canonical @@ -3316,15 +3315,32 @@ namespace System _info.Offset.Path = (ushort)_string.Length; idx = _info.Offset.Path; - ushort offset = origIdx; + int offset = origIdx; if (IsImplicitFile || ((syntaxFlags & (UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment)) == 0)) { - FindEndOfComponent(_originalUnicodeString, ref origIdx, (ushort)_originalUnicodeString.Length, c_DummyChar); + origIdx = _originalUnicodeString.Length; } else { - FindEndOfComponent(_originalUnicodeString, ref origIdx, (ushort)_originalUnicodeString.Length, - (_syntax.InFact(UriSyntaxFlags.MayHaveQuery) ? '?' : _syntax.InFact(UriSyntaxFlags.MayHaveFragment) ? '#' : c_EOL)); + ReadOnlySpan span = _originalUnicodeString.AsSpan(origIdx); + int index; + if (_syntax.InFact(UriSyntaxFlags.MayHaveQuery)) + { + if (_syntax.InFact(UriSyntaxFlags.MayHaveFragment)) + { + index = span.IndexOfAny('?', '#'); + } + else + { + index = span.IndexOf('?'); + } + } + else + { + Debug.Assert(_syntax.InFact(UriSyntaxFlags.MayHaveFragment)); + index = span.IndexOf('#'); + } + origIdx = index == -1 ? _originalUnicodeString.Length : (index + origIdx); } // Correctly escape unescape @@ -3347,7 +3363,7 @@ namespace System throw e; } - length = (ushort)_string.Length; + length = _string.Length; // We need to be sure that there isn't a '?' separated from the path by spaces. if (_string == _originalUnicodeString) { @@ -3458,12 +3474,20 @@ namespace System // if (buildIriStringFromPath) { - ushort offset = origIdx; + int offset = origIdx; if (origIdx < _originalUnicodeString.Length && _originalUnicodeString[origIdx] == '?') { - ++origIdx; // This is to exclude first '?' character from checking - FindEndOfComponent(_originalUnicodeString, ref origIdx, (ushort)_originalUnicodeString.Length, ((syntaxFlags & (UriSyntaxFlags.MayHaveFragment)) != 0) ? '#' : c_EOL); + if ((syntaxFlags & (UriSyntaxFlags.MayHaveFragment)) != 0) + { + ++origIdx; // This is to exclude first '?' character from checking + int index = _originalUnicodeString.AsSpan(origIdx).IndexOf('#'); + origIdx = index == -1 ? _originalUnicodeString.Length : (index + origIdx); + } + else + { + origIdx = _originalUnicodeString.Length; + } // Correctly escape unescape string escapedPath = EscapeUnescapeIri(_originalUnicodeString, offset, origIdx, UriComponents.Query); @@ -3485,7 +3509,7 @@ namespace System throw e; } - length = (ushort)_string.Length; + length = _string.Length; // We need to be sure that there isn't a '#' separated from the query by spaces. if (_string == _originalUnicodeString) { @@ -3494,7 +3518,7 @@ namespace System } } - _info.Offset.Query = idx; + _info.Offset.Query = (ushort)idx; fixed (char* str = _string) { @@ -3526,12 +3550,11 @@ namespace System // if (buildIriStringFromPath) { - ushort offset = origIdx; + int offset = origIdx; if (origIdx < _originalUnicodeString.Length && _originalUnicodeString[origIdx] == '#') { - ++origIdx; // This is to exclude first '#' character from checking - FindEndOfComponent(_originalUnicodeString, ref origIdx, (ushort)_originalUnicodeString.Length, c_EOL); + origIdx = _originalUnicodeString.Length; // Correctly escape unescape string escapedPath = EscapeUnescapeIri(_originalUnicodeString, offset, origIdx, UriComponents.Fragment); @@ -3553,13 +3576,13 @@ namespace System throw e; } - length = (ushort)_string.Length; + length = _string.Length; // we don't need to check _originalUnicodeString == _string because # is last part GetLengthWithoutTrailingSpaces(_string, ref length, idx); } } - _info.Offset.Fragment = idx; + _info.Offset.Fragment = (ushort)idx; fixed (char* str = _string) { @@ -3586,7 +3609,7 @@ namespace System } } } - _info.Offset.End = idx; + _info.Offset.End = (ushort)idx; Done: cF |= Flags.AllUriInfoSet; @@ -3603,10 +3626,10 @@ namespace System // returns the start of the next component position // throws UriFormatException if invalid scheme // - private static unsafe ushort ParseSchemeCheckImplicitFile(char* uriString, ushort length, + private static unsafe int ParseSchemeCheckImplicitFile(char* uriString, int length, ref ParsingError err, ref Flags flags, ref UriParser? syntax) { - ushort idx = 0; + int idx = 0; //skip whitespace while (idx < length && UriHelper.IsLWS(uriString[idx])) @@ -3626,7 +3649,7 @@ namespace System // file, ftp, http, https, uuid, etc // Note that we don't support one-letter schemes that will be put into a DOS path bucket - ushort end = idx; + int end = idx; while (end < length && uriString[end] != ':') { ++end; @@ -3638,9 +3661,9 @@ namespace System { // long = 4chars: The minimal size of a known scheme is 2 + ':' if (end != length && end >= idx + 2 && - CheckKnownSchemes((long*)(uriString + idx), (ushort)(end - idx), ref syntax)) + CheckKnownSchemes((long*)(uriString + idx), end - idx, ref syntax)) { - return (ushort)(end + 1); + return end + 1; } } @@ -3707,13 +3730,13 @@ namespace System { return 0; } - return (ushort)(end + 1); + return end + 1; } // // Quickly parses well known schemes. // nChars does not include the last ':'. Assuming there is one at the end of passed buffer - private static unsafe bool CheckKnownSchemes(long* lptr, ushort nChars, ref UriParser? syntax) + private static unsafe bool CheckKnownSchemes(long* lptr, int nChars, ref UriParser? syntax) { //NOTE beware of too short input buffers! @@ -3984,13 +4007,13 @@ namespace System // Returns position of the Path component // // Must be called in the ctor only - private unsafe ushort CheckAuthorityHelper(char* pString, ushort idx, ushort length, + private unsafe int CheckAuthorityHelper(char* pString, int idx, int length, ref ParsingError err, ref Flags flags, UriParser syntax, ref string? newHost) { int end = length; char ch; int startInput = idx; - ushort start = idx; + int start = idx; newHost = null; bool justNormalized = false; bool iriParsing = IriParsingStatic(syntax); @@ -4075,7 +4098,7 @@ namespace System bool dnsNotCanonical = ((syntaxFlags & UriSyntaxFlags.SimpleUserSyntax) == 0); if (ch == '[' && syntax.InFact(UriSyntaxFlags.AllowIPv6Host) - && IPv6AddressHelper.IsValid(pString, (int)start + 1, ref end)) + && IPv6AddressHelper.IsValid(pString, start + 1, ref end)) { flags |= Flags.IPv6HostType; @@ -4089,7 +4112,7 @@ namespace System } } else if (ch <= '9' && ch >= '0' && syntax.InFact(UriSyntaxFlags.AllowIPv4Host) && - IPv4AddressHelper.IsValid(pString, (int)start, ref end, false, StaticNotAny(flags, Flags.ImplicitFile), syntax.InFact(UriSyntaxFlags.V1_UnknownUri))) + IPv4AddressHelper.IsValid(pString, start, ref end, false, StaticNotAny(flags, Flags.ImplicitFile), syntax.InFact(UriSyntaxFlags.V1_UnknownUri))) { flags |= Flags.IPv4HostType; @@ -4149,7 +4172,7 @@ namespace System { err = ParsingError.BadHostName; flags |= Flags.UnknownHostType; - return (ushort)end; + return end; } flags &= ~Flags.HostTypeMask; } @@ -4162,16 +4185,15 @@ namespace System { int port = 0; int startPort = end; - for (idx = (ushort)(end + 1); idx < length; ++idx) + for (idx = end + 1; idx < length; ++idx) { - ushort val = unchecked((ushort)((ushort)pString[idx] - (ushort)'0')); - if ((val >= 0) && (val <= 9)) + int val = pString[idx] - '0'; + if ((uint)val <= ('9' - '0')) { if ((port = (port * 10 + val)) > 0xFFFF) break; } - else if (val == unchecked((ushort)('/' - '0')) || val == (ushort)('?' - '0') - || val == unchecked((ushort)('#' - '0'))) + else if (val == ('/' - '0') || val == ('?' - '0') || val == ('#' - '0')) { break; } @@ -4294,10 +4316,10 @@ namespace System } } } - return (ushort)end; + return end; } - private unsafe void CheckAuthorityHelperHandleDnsIri(char* pString, ushort start, int end, + private unsafe void CheckAuthorityHelperHandleDnsIri(char* pString, int start, int end, bool hasUnicode, ref Flags flags, ref bool justNormalized, ref string? newHost, ref ParsingError err) { @@ -4373,47 +4395,16 @@ namespace System } // - // Finds the end of component - // - - private unsafe void FindEndOfComponent(string input, ref ushort idx, ushort end, char delim) - { - fixed (char* str = input) - { - FindEndOfComponent(str, ref idx, end, delim); - } - } - private unsafe void FindEndOfComponent(char* str, ref ushort idx, ushort end, char delim) - { - char c = c_DummyChar; - ushort i = idx; - for (; i < end; ++i) - { - c = str[i]; - if (c == delim) - { - break; - } - else if (delim == '?' && c == '#' && (_syntax != null && _syntax.InFact(UriSyntaxFlags.MayHaveFragment))) - { - // this is a special case when deciding on Query/Fragment - break; - } - } - idx = i; - } - - // // Used by ParseRemaining as well by InternalIsWellFormedOriginalString // - private unsafe Check CheckCanonical(char* str, ref ushort idx, ushort end, char delim) + private unsafe Check CheckCanonical(char* str, ref int idx, int end, char delim) { Check res = Check.None; bool needsEscaping = false; bool foundEscaping = false; char c = c_DummyChar; - ushort i = idx; + int i = idx; for (; i < end; ++i) { c = str[i]; @@ -4805,7 +4796,7 @@ namespace System // // The passed syntax controls whether to use aggressive compression or the one specified in RFC 2396 // - private static char[] Compress(char[] dest, ushort start, ref int destLength, UriParser syntax) + private static char[] Compress(char[] dest, int start, ref int destLength, UriParser syntax) { ushort slashCount = 0; ushort lastSlash = 0; diff --git a/src/libraries/System.Private.Uri/src/System/UriExt.cs b/src/libraries/System.Private.Uri/src/System/UriExt.cs index 17fc3fd..8b51312 100644 --- a/src/libraries/System.Private.Uri/src/System/UriExt.cs +++ b/src/libraries/System.Private.Uri/src/System/UriExt.cs @@ -411,7 +411,7 @@ namespace System fixed (char* str = _string) { - ushort idx = 0; + int idx = 0; // // For a relative Uri we only care about escaping and backslashes // @@ -422,7 +422,7 @@ namespace System { return false; } - return (CheckCanonical(str, ref idx, (ushort)_string.Length, c_EOL) + return (CheckCanonical(str, ref idx, _string.Length, c_EOL) & (Check.BackslashInPath | Check.EscapedCanonical)) == Check.EscapedCanonical; } @@ -471,7 +471,7 @@ namespace System // checking on scheme:\\ or file://// if (InFact(Flags.AuthorityFound)) { - idx = (ushort)(_info.Offset.Scheme + _syntax.SchemeName.Length + 2); + idx = _info.Offset.Scheme + _syntax.SchemeName.Length + 2; if (idx >= _info.Offset.User || _string[idx - 1] == '\\' || _string[idx] == '\\') return false; @@ -510,7 +510,7 @@ namespace System if ((_flags & Flags.CanonicalDnsHost) == 0 && HostType != Flags.IPv6HostType) { idx = _info.Offset.User; - Check result = CheckCanonical(str, ref idx, (ushort)_info.Offset.Path, '/'); + Check result = CheckCanonical(str, ref idx, _info.Offset.Path, '/'); if (((result & (Check.ReservedFound | Check.BackslashInPath | Check.EscapedCanonical)) != Check.EscapedCanonical) && (!_iriParsing || (_iriParsing @@ -525,7 +525,7 @@ namespace System if ((_flags & (Flags.SchemeNotCanonical | Flags.AuthorityFound)) == (Flags.SchemeNotCanonical | Flags.AuthorityFound)) { - idx = (ushort)_syntax.SchemeName.Length; + idx = _syntax.SchemeName.Length; while (str[idx++] != ':'); if (idx + 1 >= _string.Length || str[idx] != '/' || str[idx + 1] != '/') return false; @@ -884,7 +884,7 @@ namespace System { fixed (char* otherPtr = other) { - return UriHelper.TestForSubPath(selfPtr, (ushort)self.Length, otherPtr, (ushort)other.Length, + return UriHelper.TestForSubPath(selfPtr, self.Length, otherPtr, other.Length, IsUncOrDosPath || uriLink.IsUncOrDosPath); } } diff --git a/src/libraries/System.Private.Uri/src/System/UriHelper.cs b/src/libraries/System.Private.Uri/src/System/UriHelper.cs index 95e2c05..3e354bd 100644 --- a/src/libraries/System.Private.Uri/src/System/UriHelper.cs +++ b/src/libraries/System.Private.Uri/src/System/UriHelper.cs @@ -33,10 +33,10 @@ namespace System // ASSUMES that strings like http://host/Path/Path/MoreDir/../../ have been canonicalized before going to this method. // ASSUMES that back slashes already have been converted if applicable. // - internal static unsafe bool TestForSubPath(char* selfPtr, ushort selfLength, char* otherPtr, ushort otherLength, + internal static unsafe bool TestForSubPath(char* selfPtr, int selfLength, char* otherPtr, int otherLength, bool ignoreCase) { - ushort i = 0; + int i = 0; char chSelf; char chOther; -- 2.7.4