From 588d9cdb1122561c37361be5a50733e83544f61a Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Tue, 12 Dec 2017 11:55:48 -0800 Subject: [PATCH] Use Utf8Parser instead of custom code (#1200) --- .../LengthPrefixedTextMessageParser.cs | 95 +------------------ 1 file changed, 2 insertions(+), 93 deletions(-) diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/LengthPrefixedTextMessageParser.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/LengthPrefixedTextMessageParser.cs index 686c25e95f..6fb57c1288 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/LengthPrefixedTextMessageParser.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/LengthPrefixedTextMessageParser.cs @@ -2,13 +2,13 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Buffers.Text; using System.Text; namespace Microsoft.AspNetCore.SignalR.Internal.Encoders { public static class LengthPrefixedTextMessageParser { - private const int Int32OverflowLength = 10; private const char FieldDelimiter = ':'; private const char MessageDelimiter = ';'; @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Encoders var lengthSpan = buffer.Slice(0, index); - if (!TryParseInt32(lengthSpan, out length, out var bytesConsumed) || bytesConsumed < lengthSpan.Length) + if (!Utf8Parser.TryParse(buffer, out length, out var bytesConsumed) || bytesConsumed < lengthSpan.Length) { throw new FormatException($"Invalid length: '{Encoding.UTF8.GetString(lengthSpan.ToArray())}'"); } @@ -90,96 +90,5 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Encoders return true; } - - private static bool TryParseInt32(ReadOnlySpan text, out int value, out int bytesConsumed) - { - if (text.Length < 1) - { - bytesConsumed = 0; - value = default; - return false; - } - - int indexOfFirstDigit = 0; - int sign = 1; - if (text[0] == '-') - { - indexOfFirstDigit = 1; - sign = -1; - } - else if (text[0] == '+') - { - indexOfFirstDigit = 1; - } - - int overflowLength = Int32OverflowLength + indexOfFirstDigit; - - // Parse the first digit separately. If invalid here, we need to return false. - int firstDigit = text[indexOfFirstDigit] - 48; // '0' - if (firstDigit < 0 || firstDigit > 9) - { - bytesConsumed = 0; - value = default; - return false; - } - int parsedValue = firstDigit; - - if (text.Length < overflowLength) - { - // Length is less than Int32OverflowLength; overflow is not possible - for (int index = indexOfFirstDigit + 1; index < text.Length; index++) - { - int nextDigit = text[index] - 48; // '0' - if (nextDigit < 0 || nextDigit > 9) - { - bytesConsumed = index; - value = parsedValue * sign; - return true; - } - parsedValue = parsedValue * 10 + nextDigit; - } - } - else - { - // Length is greater than Int32OverflowLength; overflow is only possible after Int32OverflowLength - // digits. There may be no overflow after Int32OverflowLength if there are leading zeroes. - for (int index = indexOfFirstDigit + 1; index < overflowLength - 1; index++) - { - int nextDigit = text[index] - 48; // '0' - if (nextDigit < 0 || nextDigit > 9) - { - bytesConsumed = index; - value = parsedValue * sign; - return true; - } - parsedValue = parsedValue * 10 + nextDigit; - } - for (int index = overflowLength - 1; index < text.Length; index++) - { - int nextDigit = text[index] - 48; // '0' - if (nextDigit < 0 || nextDigit > 9) - { - bytesConsumed = index; - value = parsedValue * sign; - return true; - } - // If parsedValue > (int.MaxValue / 10), any more appended digits will cause overflow. - // if parsedValue == (int.MaxValue / 10), any nextDigit greater than 7 or 8 (depending on sign) implies overflow. - bool positive = sign > 0; - bool nextDigitTooLarge = nextDigit > 8 || (positive && nextDigit > 7); - if (parsedValue > int.MaxValue / 10 || parsedValue == int.MaxValue / 10 && nextDigitTooLarge) - { - bytesConsumed = 0; - value = default; - return false; - } - parsedValue = parsedValue * 10 + nextDigit; - } - } - - bytesConsumed = text.Length; - value = parsedValue * sign; - return true; - } } }