diff --git a/src/libraries/Common/src/System/HexConverter.cs b/src/libraries/Common/src/System/HexConverter.cs index 261009571f8cfa..7c9b5fb7cdbafa 100644 --- a/src/libraries/Common/src/System/HexConverter.cs +++ b/src/libraries/Common/src/System/HexConverter.cs @@ -370,32 +370,38 @@ private static bool TryDecodeFromUtf16_Scalar(ReadOnlySpan chars, Span= 0; } + /// Converts a hex character to its integer value. + /// The integer value of the hex character, or -1 if the character is not a valid hex character. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromChar(int c) { - return c >= CharToHexLookup.Length ? 0xFF : CharToHexLookup[c]; + return CharToHexLookup[Math.Min(c, 0xFF)]; } + /// Converts an upper hex character to its integer value. + /// The integer value of the upper hex character, or -1 if the character is not a valid upper hex character. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromUpperChar(int c) { - return c > 71 ? 0xFF : CharToHexLookup[c]; + return CharToHexLookup[Math.Min(c, 'F' + 1)]; } + /// Converts a lower hex character to its integer value. + /// The integer value of the lower hex character, or -1 if the character is not a valid lower hex character. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromLowerChar(int c) { @@ -405,7 +411,7 @@ public static int FromLowerChar(int c) if ((uint)(c - 'a') <= 'f' - 'a') return c - 'a' + 10; - return 0xFF; + return -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -436,7 +442,7 @@ public static bool IsHexChar(int c) return (long)(shift & mask) < 0 ? true : false; } - return FromChar(c) != 0xFF; + return FromChar(c) >= 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -451,25 +457,25 @@ public static bool IsHexLowerChar(int c) return (uint)(c - '0') <= 9 || (uint)(c - 'a') <= ('f' - 'a'); } - /// Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit. - public static ReadOnlySpan CharToHexLookup => + /// Map from an ASCII char to its hex value, e.g. arr['b'] == 11. -1 means it's not a hex digit. + public static ReadOnlySpan CharToHexLookup => [ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 15 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 31 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 47 - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 63 - 0xFF, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 79 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 95 - 0xFF, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 111 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 127 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 143 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 159 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 175 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 191 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 207 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 223 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 239 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 255 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 15 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 31 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 47 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 63 + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 79 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 95 + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 111 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 127 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 143 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 159 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 175 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 191 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 207 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 223 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 239 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 255 ]; } } diff --git a/src/libraries/Common/src/System/Net/IPv4AddressHelper.Common.cs b/src/libraries/Common/src/System/Net/IPv4AddressHelper.Common.cs index 0f57374b49616f..6615f6537df8a2 100644 --- a/src/libraries/Common/src/System/Net/IPv4AddressHelper.Common.cs +++ b/src/libraries/Common/src/System/Net/IPv4AddressHelper.Common.cs @@ -263,9 +263,10 @@ internal static unsafe long ParseNonCanonical(TChar* name, int start, ref ch = ToUShort(name[current]); int digitValue = HexConverter.FromChar(ch); - if (digitValue >= numberBase) + // Unsigned overflow indicates an invalid character or a terminator + if ((uint)digitValue >= (uint)numberBase) { - break; // Invalid/terminator + break; } currentValue = (currentValue * numberBase) + digitValue; diff --git a/src/libraries/Common/src/System/Net/IPv6AddressHelper.Common.cs b/src/libraries/Common/src/System/Net/IPv6AddressHelper.Common.cs index d27cd18b8d56c3..26285aaf0791af 100644 --- a/src/libraries/Common/src/System/Net/IPv6AddressHelper.Common.cs +++ b/src/libraries/Common/src/System/Net/IPv6AddressHelper.Common.cs @@ -420,7 +420,7 @@ internal static void Parse(ReadOnlySpan address, scoped Span span, out byte value [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryDecodeHexDigit(char c, out byte value) { - value = (byte)HexConverter.FromChar((int)c); - return value != 0xFF; // invalid hex digit + int result = HexConverter.FromChar(c); + value = (byte)result; + return result >= 0; } // Allowed baggage key characters: diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderParser.cs index 180a25131c7582..a249bf873fc5b1 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderParser.cs @@ -288,7 +288,7 @@ private static bool TryReadUnknownPercentEncodedAlpnProtocolName(ReadOnlySpan= 0) { // valid 4 hex chars ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4); pos += 5; @@ -448,7 +448,7 @@ private static string UrlDecodeStringFromStringInternal(string s, Encoding e) int h1 = HexConverter.FromChar(s[pos + 1]); int h2 = HexConverter.FromChar(s[pos + 2]); - if ((h1 | h2) != 0xFF) + if ((h1 | h2) >= 0) { // valid 2 hex chars byte b = (byte)((h1 << 4) | h2); pos += 2; diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/PhysicalAddress.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/PhysicalAddress.cs index 0bf04e204e8350..b14971a37613dd 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/PhysicalAddress.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/PhysicalAddress.cs @@ -159,7 +159,7 @@ public static bool TryParse(ReadOnlySpan address, [NotNullWhen(true)] out { int character = address[i]; int tmp; - if ((tmp = HexConverter.FromChar(character)) == 0xFF) + if ((tmp = HexConverter.FromChar(character)) < 0) { if (delimiter == character && validCount == validSegmentLength) { diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/StringParsingHelpers.Connections.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/StringParsingHelpers.Connections.cs index 248ce38b5d2027..e75653d681a8f0 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/StringParsingHelpers.Connections.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/StringParsingHelpers.Connections.cs @@ -388,7 +388,7 @@ private static IPAddress ParseIPv6HexString(ReadOnlySpan hexAddress, bool private static byte HexToByte(char val) { int result = HexConverter.FromChar(val); - if (result == 0xFF) + if (result < 0) { throw ExceptionHelper.CreateForParseFailure(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.X.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.X.cs index 543ee68baaecb4..5ed9bb427b1c3e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.X.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.X.cs @@ -14,20 +14,20 @@ private static bool TryParseByteX(ReadOnlySpan source, out byte value, out return false; } byte nextCharacter; - byte nextDigit; + int nextDigit; - ReadOnlySpan hexLookup = HexConverter.CharToHexLookup; + ReadOnlySpan hexLookup = HexConverter.CharToHexLookup; // Parse the first digit separately. If invalid here, we need to return false. nextCharacter = source[0]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = 0; value = default; return false; } - uint parsedValue = nextDigit; + uint parsedValue = (uint)nextDigit; if (source.Length <= ParserHelpers.ByteOverflowLengthHex) { @@ -36,13 +36,13 @@ private static bool TryParseByteX(ReadOnlySpan source, out byte value, out { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = (byte)(parsedValue); return true; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } } else @@ -53,19 +53,19 @@ private static bool TryParseByteX(ReadOnlySpan source, out byte value, out { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = (byte)(parsedValue); return true; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } for (int index = ParserHelpers.ByteOverflowLengthHex; index < source.Length; index++) { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = (byte)(parsedValue); @@ -78,7 +78,7 @@ private static bool TryParseByteX(ReadOnlySpan source, out byte value, out value = default; return false; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } } @@ -96,20 +96,20 @@ private static bool TryParseUInt16X(ReadOnlySpan source, out ushort value, return false; } byte nextCharacter; - byte nextDigit; + int nextDigit; - ReadOnlySpan hexLookup = HexConverter.CharToHexLookup; + ReadOnlySpan hexLookup = HexConverter.CharToHexLookup; // Parse the first digit separately. If invalid here, we need to return false. nextCharacter = source[0]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = 0; value = default; return false; } - uint parsedValue = nextDigit; + uint parsedValue = (uint)nextDigit; if (source.Length <= ParserHelpers.Int16OverflowLengthHex) { @@ -118,13 +118,13 @@ private static bool TryParseUInt16X(ReadOnlySpan source, out ushort value, { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = (ushort)(parsedValue); return true; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } } else @@ -135,19 +135,19 @@ private static bool TryParseUInt16X(ReadOnlySpan source, out ushort value, { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = (ushort)(parsedValue); return true; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } for (int index = ParserHelpers.Int16OverflowLengthHex; index < source.Length; index++) { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = (ushort)(parsedValue); @@ -160,7 +160,7 @@ private static bool TryParseUInt16X(ReadOnlySpan source, out ushort value, value = default; return false; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } } @@ -178,20 +178,20 @@ private static bool TryParseUInt32X(ReadOnlySpan source, out uint value, o return false; } byte nextCharacter; - byte nextDigit; + int nextDigit; - ReadOnlySpan hexLookup = HexConverter.CharToHexLookup; + ReadOnlySpan hexLookup = HexConverter.CharToHexLookup; // Parse the first digit separately. If invalid here, we need to return false. nextCharacter = source[0]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = 0; value = default; return false; } - uint parsedValue = nextDigit; + uint parsedValue = (uint)nextDigit; if (source.Length <= ParserHelpers.Int32OverflowLengthHex) { @@ -200,13 +200,13 @@ private static bool TryParseUInt32X(ReadOnlySpan source, out uint value, o { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = parsedValue; return true; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } } else @@ -217,19 +217,19 @@ private static bool TryParseUInt32X(ReadOnlySpan source, out uint value, o { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = parsedValue; return true; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } for (int index = ParserHelpers.Int32OverflowLengthHex; index < source.Length; index++) { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = parsedValue; @@ -242,7 +242,7 @@ private static bool TryParseUInt32X(ReadOnlySpan source, out uint value, o value = default; return false; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } } @@ -260,20 +260,20 @@ private static bool TryParseUInt64X(ReadOnlySpan source, out ulong value, return false; } byte nextCharacter; - byte nextDigit; + int nextDigit; - ReadOnlySpan hexLookup = HexConverter.CharToHexLookup; + ReadOnlySpan hexLookup = HexConverter.CharToHexLookup; // Parse the first digit separately. If invalid here, we need to return false. nextCharacter = source[0]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = 0; value = default; return false; } - ulong parsedValue = nextDigit; + ulong parsedValue = (uint)nextDigit; if (source.Length <= ParserHelpers.Int64OverflowLengthHex) { @@ -282,13 +282,13 @@ private static bool TryParseUInt64X(ReadOnlySpan source, out ulong value, { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = parsedValue; return true; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } } else @@ -299,19 +299,19 @@ private static bool TryParseUInt64X(ReadOnlySpan source, out ulong value, { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = parsedValue; return true; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } for (int index = ParserHelpers.Int64OverflowLengthHex; index < source.Length; index++) { nextCharacter = source[index]; nextDigit = hexLookup[nextCharacter]; - if (nextDigit == 0xFF) + if (nextDigit < 0) { bytesConsumed = index; value = parsedValue; @@ -324,7 +324,7 @@ private static bool TryParseUInt64X(ReadOnlySpan source, out ulong value, value = default; return false; } - parsedValue = (parsedValue << 4) + nextDigit; + parsedValue = (parsedValue << 4) + (uint)nextDigit; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Guid.cs b/src/libraries/System.Private.CoreLib/src/System/Guid.cs index 2c24b8fdd1fe16..2269108d9015dd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Guid.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Guid.cs @@ -815,16 +815,14 @@ private static bool TryParseExactX(ReadOnlySpan guidString, ref Gu [MethodImpl(MethodImplOptions.AggressiveInlining)] private static byte DecodeByte(TChar ch1, TChar ch2, ref int invalidIfNegative) where TChar : unmanaged, IUtfChar { - ReadOnlySpan lookup = HexConverter.CharToHexLookup; + ReadOnlySpan lookup = HexConverter.CharToHexLookup; Debug.Assert(lookup.Length == 256); - int upper = (sbyte)lookup[byte.CreateTruncating(ch1)]; - int lower = (sbyte)lookup[byte.CreateTruncating(ch2)]; - int result = (upper << 4) | lower; - uint c1 = TChar.CastToUInt32(ch1); - uint c2 = TChar.CastToUInt32(ch2); - // Result will be negative if ch1 or/and ch2 are greater than 0xFF - result = (c1 | c2) >> 8 == 0 ? result : -1; + uint c1 = typeof(TChar) == typeof(byte) ? TChar.CastToUInt32(ch1) : Math.Min(TChar.CastToUInt32(ch1), 0x7F); + uint c2 = typeof(TChar) == typeof(byte) ? TChar.CastToUInt32(ch2) : Math.Min(TChar.CastToUInt32(ch2), 0x7F); + int upper = lookup[(int)c1]; + int lower = lookup[(int)c2]; + int result = (upper << 4) | lower; invalidIfNegative |= result; return (byte)result; } @@ -867,7 +865,7 @@ private static bool TryParseHex(ReadOnlySpan guidString, out uint { int c = int.CreateTruncating(guidString[i]); int numValue = HexConverter.FromChar(c); - if (numValue == 0xFF) + if (numValue < 0) { if (processedDigits > 8) overflow = true; result = 0; diff --git a/src/libraries/System.Private.CoreLib/src/System/Net/WebUtility.cs b/src/libraries/System.Private.CoreLib/src/System/Net/WebUtility.cs index 5acf86778135ba..8b05dfc0881f98 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Net/WebUtility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Net/WebUtility.cs @@ -473,7 +473,7 @@ private static int IndexOfHtmlEncodingChar(ReadOnlySpan input) int h1 = HexConverter.FromChar(value[pos + 1]); int h2 = HexConverter.FromChar(value[pos + 2]); - if ((h1 | h2) != 0xFF) + if ((h1 | h2) >= 0) { // valid 2 hex chars byte b = (byte)((h1 << 4) | h2); pos += 2; @@ -531,7 +531,7 @@ private static int IndexOfHtmlEncodingChar(ReadOnlySpan input) int h1 = HexConverter.FromChar(bytes[pos + 1]); int h2 = HexConverter.FromChar(bytes[pos + 2]); - if ((h1 | h2) != 0xFF) + if ((h1 | h2) >= 0) { // valid 2 hex chars b = (byte)((h1 << 4) | h2); i += 2; diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs index d063d729297e95..b81af7e6e82881 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs @@ -731,7 +731,7 @@ private int GetHexCharEntity(int offset, int length) { byte ch = buffer[offset + i]; int digit = HexConverter.FromChar(ch); - if (digit == 0xFF) + if (digit < 0) XmlExceptionHelper.ThrowInvalidCharRef(_reader); Debug.Assert(digit >= 0 && digit < 16); value = value * 16 + digit; diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index 9e972ee7000721..34b3d72c89f4c1 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -1507,7 +1507,7 @@ public static bool IsHexDigit(char character) public static int FromHex(char digit) { int result = HexConverter.FromChar(digit); - if (result == 0xFF) + if (result < 0) { throw new ArgumentException(null, nameof(digit)); } diff --git a/src/libraries/System.Private.Uri/src/System/UriHelper.cs b/src/libraries/System.Private.Uri/src/System/UriHelper.cs index 56ccaa31ef0053..f86b80ed4e1e37 100644 --- a/src/libraries/System.Private.Uri/src/System/UriHelper.cs +++ b/src/libraries/System.Private.Uri/src/System/UriHelper.cs @@ -521,7 +521,7 @@ internal static char DecodeHexChars(int first, int second) int a = HexConverter.FromChar(first); int b = HexConverter.FromChar(second); - if ((a | b) == 0xFF) + if ((a | b) < 0) { // either a or b is 0xFF (invalid) return Uri.c_DummyChar; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/BinHexDecoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/BinHexDecoder.cs index 502f3d5d4d1446..b3d8d9c0d7a238 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/BinHexDecoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/BinHexDecoder.cs @@ -152,7 +152,7 @@ private static void Decode(ReadOnlySpan chars, char ch = chars[iChar]; int val = HexConverter.FromChar(ch); - if (val != 0xFF) + if (val >= 0) { halfByte = (byte)val; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs index b169310c64c0c6..42f98632032e67 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs @@ -7234,7 +7234,7 @@ private int ParseNumericCharRefInline(int startPos, bool expand, StringBuilder? while (true) { int ch = HexConverter.FromChar(chars[pos]); - if (ch == 0xFF) + if (ch < 0) break; val = checked(val * 16 + ch); pos++; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs index efe07812b079cf..83a1e28b0370ff 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlConvert.cs @@ -288,7 +288,7 @@ public partial class XmlConvert private static int FromHex(char digit) { - return HexConverter.FromChar(digit); + return (byte)HexConverter.FromChar(digit); } internal static byte[] FromBinHexString(ReadOnlySpan s, bool allowOddCount) diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs index 137ac1878ed2e1..d6ee9367591e38 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs @@ -1485,7 +1485,7 @@ private char ScanHex(int c) { char ch = _pattern[_pos++]; int result = HexConverter.FromChar(ch); - if (result == 0xFF) + if (result < 0) { break; } diff --git a/src/libraries/System.Web.HttpUtility/src/System/Web/Util/HttpEncoder.cs b/src/libraries/System.Web.HttpUtility/src/System/Web/Util/HttpEncoder.cs index 46227356574632..f26351063a79e3 100644 --- a/src/libraries/System.Web.HttpUtility/src/System/Web/Util/HttpEncoder.cs +++ b/src/libraries/System.Web.HttpUtility/src/System/Web/Util/HttpEncoder.cs @@ -223,7 +223,7 @@ internal static byte[] UrlDecode(ReadOnlySpan bytes) int h1 = HexConverter.FromChar(bytes[i + 1]); int h2 = HexConverter.FromChar(bytes[i + 2]); - if ((h1 | h2) != 0xFF) + if ((h1 | h2) >= 0) { // valid 2 hex chars b = (byte)((h1 << 4) | h2); @@ -273,7 +273,7 @@ internal static byte[] UrlDecode(ReadOnlySpan bytes) int h3 = HexConverter.FromChar(bytes[pos + 4]); int h4 = HexConverter.FromChar(bytes[pos + 5]); - if ((h1 | h2 | h3 | h4) != 0xFF) + if ((h1 | h2 | h3 | h4) >= 0) { // valid 4 hex chars char ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4); i += 5; @@ -288,7 +288,7 @@ internal static byte[] UrlDecode(ReadOnlySpan bytes) int h1 = HexConverter.FromChar(bytes[pos + 1]); int h2 = HexConverter.FromChar(bytes[pos + 2]); - if ((h1 | h2) != 0xFF) + if ((h1 | h2) >= 0) { // valid 2 hex chars b = (byte)((h1 << 4) | h2); i += 2; @@ -346,7 +346,7 @@ internal static string UrlDecode(ReadOnlySpan value, Encoding encoding) int h3 = HexConverter.FromChar(value[pos + 4]); int h4 = HexConverter.FromChar(value[pos + 5]); - if ((h1 | h2 | h3 | h4) != 0xFF) + if ((h1 | h2 | h3 | h4) >= 0) { // valid 4 hex chars ch = (char)((h1 << 12) | (h2 << 8) | (h3 << 4) | h4); pos += 5; @@ -361,7 +361,7 @@ internal static string UrlDecode(ReadOnlySpan value, Encoding encoding) int h1 = HexConverter.FromChar(value[pos + 1]); int h2 = HexConverter.FromChar(value[pos + 2]); - if ((h1 | h2) != 0xFF) + if ((h1 | h2) >= 0) { // valid 2 hex chars byte b = (byte)((h1 << 4) | h2); pos += 2;