Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit c6f266f

Browse files
committed
Change FormatFixed to avoid bounds checks
Match the original native code's use of pointers.
1 parent 523ee2d commit c6f266f

File tree

1 file changed

+32
-34
lines changed

1 file changed

+32
-34
lines changed

src/mscorlib/shared/System/Number.Formatting.cs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -977,76 +977,74 @@ private static unsafe void FormatFixed(ref ValueStringBuilder sb, ref NumberBuff
977977

978978
if (digPos > 0)
979979
{
980-
int digLength = string.wcslen(dig);
981-
982980
if (groupDigits != null)
983981
{
984982
int groupSizeIndex = 0; // Index into the groupDigits array.
985983
int groupSizeCount = groupDigits[groupSizeIndex]; // The current total of group size.
986-
int groupSizeLen = groupDigits.Length; // The length of groupDigits array.
987984
int bufferSize = digPos; // The length of the result buffer string.
988-
int groupSeparatorLen = sGroup.Length; // The length of the group separator string.
989985
int groupSize = 0; // The current group size.
990986

991987
// Find out the size of the string buffer for the result.
992-
if (groupSizeLen != 0) // You can pass in 0 length arrays
988+
if (groupDigits.Length != 0) // You can pass in 0 length arrays
993989
{
994990
while (digPos > groupSizeCount)
995991
{
996992
groupSize = groupDigits[groupSizeIndex];
997993
if (groupSize == 0)
998994
break;
999995

1000-
bufferSize += groupSeparatorLen;
1001-
if (groupSizeIndex < groupSizeLen - 1)
996+
bufferSize += sGroup.Length;
997+
if (groupSizeIndex < groupDigits.Length - 1)
1002998
groupSizeIndex++;
1003999

10041000
groupSizeCount += groupDigits[groupSizeIndex];
10051001
if (groupSizeCount < 0 || bufferSize < 0)
10061002
throw new ArgumentOutOfRangeException(); // If we overflow
10071003
}
1008-
if (groupSizeCount == 0) // If you passed in an array with one entry as 0, groupSizeCount == 0
1009-
groupSize = 0;
1010-
else
1011-
groupSize = groupDigits[0];
1004+
1005+
groupSize = groupSizeCount == 0 ? 0 : groupDigits[0]; // If you passed in an array with one entry as 0, groupSizeCount == 0
10121006
}
10131007

1014-
Span<char> tmpBuffer = sb.AppendSpan(bufferSize);
10151008
groupSizeIndex = 0;
10161009
int digitCount = 0;
1017-
int digStart;
1018-
digStart = (digPos < digLength) ? digPos : digLength;
1019-
for (int i = digPos - 1; i >= 0; i--)
1010+
int digLength = string.wcslen(dig);
1011+
int digStart = (digPos < digLength) ? digPos : digLength;
1012+
fixed (char* spanPtr = &sb.AppendSpan(bufferSize).DangerousGetPinnableReference())
10201013
{
1021-
tmpBuffer[--bufferSize] = (i < digStart) ? dig[i] : '0';
1022-
1023-
if (groupSize > 0)
1014+
char* p = spanPtr + bufferSize - 1;
1015+
for (int i = digPos - 1; i >= 0; i--)
10241016
{
1025-
digitCount++;
1026-
if ((digitCount == groupSize) && (i != 0))
1027-
{
1028-
for (int j = groupSeparatorLen - 1; j >= 0; j--)
1029-
tmpBuffer[--bufferSize] = sGroup[j];
1017+
*(p--) = (i < digStart) ? dig[i] : '0';
10301018

1031-
if (groupSizeIndex < groupSizeLen - 1)
1019+
if (groupSize > 0)
1020+
{
1021+
digitCount++;
1022+
if ((digitCount == groupSize) && (i != 0))
10321023
{
1033-
groupSizeIndex++;
1034-
groupSize = groupDigits[groupSizeIndex];
1024+
for (int j = sGroup.Length - 1; j >= 0; j--)
1025+
*(p--) = sGroup[j];
1026+
1027+
if (groupSizeIndex < groupDigits.Length - 1)
1028+
{
1029+
groupSizeIndex++;
1030+
groupSize = groupDigits[groupSizeIndex];
1031+
}
1032+
digitCount = 0;
10351033
}
1036-
digitCount = 0;
10371034
}
10381035
}
1039-
}
10401036

1041-
dig += digStart;
1037+
Debug.Assert(p >= spanPtr - 1, "Underflow");
1038+
dig += digStart;
1039+
}
10421040
}
10431041
else
10441042
{
1045-
int digits = Math.Min(digLength, digPos);
1046-
sb.Append(dig, digits);
1047-
dig += digits;
1048-
if (digPos > digLength)
1049-
sb.Append('0', digPos - digLength);
1043+
do
1044+
{
1045+
sb.Append(*dig != 0 ? *dig++ : '0');
1046+
}
1047+
while (--digPos > 0);
10501048
}
10511049
}
10521050
else

0 commit comments

Comments
 (0)