Skip to content

Commit 3aba12d

Browse files
committed
Add support for parsing large integers causing overflows in longs
1 parent d701677 commit 3aba12d

3 files changed

Lines changed: 32 additions & 6 deletions

File tree

ServiceStack.Text/src/ServiceStack.Text/DefaultMemory.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ internal static ulong ParseUInt64(ReadOnlySpan<char> value)
10161016
{
10171017
state = ParseState.TrailingWhite;
10181018
}
1019-
else if (c > '0' && c <= '9')
1019+
else if (c is > '0' and <= '9')
10201020
{
10211021
result = (ulong) (c - '0');
10221022
state = ParseState.Number;
@@ -1026,15 +1026,14 @@ internal static ulong ParseUInt64(ReadOnlySpan<char> value)
10261026

10271027
break;
10281028
case ParseState.Number:
1029-
if (c >= '0' && c <= '9')
1029+
if (c is >= '0' and <= '9')
10301030
{
10311031
checked
10321032
{
10331033
result = 10 * result + (ulong) (c - '0');
10341034
}
10351035

1036-
if (result > maxValue
1037-
) //check only minvalue, because in absolute value it's greater than maxvalue
1036+
if (result > maxValue) //check only minvalue, because in absolute value it's greater than maxvalue
10381037
throw DefaultMemory.CreateOverflowException(maxValue);
10391038
}
10401039
else if (JsonUtils.IsWhiteSpace(c))

ServiceStack.Text/src/ServiceStack.Text/StringSpanExtensions.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,38 @@ public static Guid ParseGuid(this ReadOnlySpan<char> value) =>
183183
public static object ParseSignedInteger(this ReadOnlySpan<char> value)
184184
{
185185
var longValue = ParseInt64(value);
186-
if (longValue >= int.MinValue && longValue <= int.MaxValue)
186+
if (longValue is >= int.MinValue and <= int.MaxValue)
187187
return (int)longValue;
188188
return longValue;
189189
}
190190

191+
public static object ParseUnsignedInteger(this ReadOnlySpan<char> value)
192+
{
193+
var longValue = ParseUInt64(value);
194+
if (longValue <= uint.MaxValue)
195+
return (uint)longValue;
196+
return longValue;
197+
}
198+
199+
public static object ParseInteger(this ReadOnlySpan<char> value)
200+
{
201+
try
202+
{
203+
return ParseSignedInteger(value);
204+
}
205+
catch (OverflowException)
206+
{
207+
try
208+
{
209+
return ParseUInt64(value);
210+
}
211+
catch (OverflowException)
212+
{
213+
return ParseDecimal(value);
214+
}
215+
}
216+
}
217+
191218
public static bool TryReadLine(this ReadOnlySpan<char> text, out ReadOnlySpan<char> line, ref int startIndex)
192219
{
193220
if (startIndex >= text.Length)

ServiceStack/src/ServiceStack.Common/Script/JsToken.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ public static ReadOnlySpan<char> ParseJsToken(this ReadOnlySpan<char> literal, o
484484
if ((firstDecimalPos > 0 && firstDecimalPos < i) || hasExponent)
485485
token = new JsLiteral(ScriptConfig.ParseRealNumber(numLiteral));
486486
else
487-
token = new JsLiteral(numLiteral.ParseSignedInteger());
487+
token = new JsLiteral(numLiteral.ParseInteger());
488488

489489
if (hasMemberSuffix)
490490
{

0 commit comments

Comments
 (0)