Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/libraries/Common/src/System/Number.Formatting.Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,20 +147,29 @@ internal static char ParseFormatSpecifier(ReadOnlySpan<char> format, out int dig
// digits. Further, for compat, we need to stop when we hit a null char.
int n = 0;
int i = 1;
bool precisionTooLarge = false;
while ((uint)i < (uint)format.Length && char.IsAsciiDigit(format[i]))
{
// Check if we are about to overflow past our limit of 9 digits
if (n >= 100_000_000)
{
ThrowHelper.ThrowFormatException_BadFormatSpecifier();
precisionTooLarge = true;
}
else
{
n = (n * 10) + format[i] - '0';
}
n = (n * 10) + format[i++] - '0';
i++;
}

// If we're at the end of the digits rather than having stopped because we hit something
// other than a digit or overflowed, return the standard format info.
// other than a digit, this is a standard format.
if ((uint)i >= (uint)format.Length || format[i] == '\0')
{
if (precisionTooLarge)
{
ThrowHelper.ThrowFormatException_BadFormatSpecifier();
}

digits = n;
return c;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,8 @@ public static void RunCustomFormatLiterals()
RunCustomFormatToStringTests(s_random, "0\"\\\"", CultureInfo.CurrentCulture.NumberFormat.NegativeSign, 1, ExtraFormatter(ZeroFormatter, "\\"));
RunCustomFormatToStringTests(s_random, "#\',\'%", CultureInfo.CurrentCulture.NumberFormat.NegativeSign, 0, ExtraFormatter(PercentSymbolFormatter, ",", CultureInfo.CurrentCulture.NumberFormat.PercentSymbol.Length));
RunCustomFormatToStringTests(s_random, "000\",\".000", CultureInfo.CurrentCulture.NumberFormat.NegativeSign, 3, ExtraFormatter(DecimalPointFormatter, ",", CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.Length + 3));
VerifyToString("7", "A1111111111-0", "A1111111111-7");
VerifyToString("7", "A1234567890Z", "A1234567897Z");
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ public static IEnumerable<object[]> ToString_TestData()
}

NumberFormatInfo invariantFormat = NumberFormatInfo.InvariantInfo;
yield return new object[] { 7, "A1111111111-0", invariantFormat, "A1111111111-7" };
yield return new object[] { 7, "A1234567890Z", invariantFormat, "A1234567897Z" };
yield return new object[] { 32, "C100", invariantFormat, "\u00A432.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" };
yield return new object[] { 32, "P100", invariantFormat, "3,200.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 %" };
yield return new object[] { 32, "D100", invariantFormat, "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032" };
Expand Down Expand Up @@ -197,6 +199,8 @@ public static void ToString_InvalidFormat_ThrowsFormatException()
int i = 123;
Assert.Throws<FormatException>(() => i.ToString("Y")); // Invalid format
Assert.Throws<FormatException>(() => i.ToString("Y", null)); // Invalid format
Assert.Throws<FormatException>(() => i.ToString("D1000000000")); // Precision too large
Assert.Throws<FormatException>(() => i.ToString("A1234567890")); // Standard-shaped format
}

public static IEnumerable<object[]> Parse_Valid_TestData()
Expand Down
Loading