Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b9f56d4

Browse files
committed
Defensive for custom float-point
1 parent c60098b commit b9f56d4

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

src/libraries/System.Private.CoreLib/src/System/Numerics/TotalOrderIeee754Comparer.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,28 @@ static int CompareSignificant(T x, T y)
142142
// To match the integer semantic comparison above, here we compare all the significant bits
143143
// Revisit this if decimals are added
144144

145-
Span<byte> significantX = stackalloc byte[x!.GetSignificandByteCount()];
146-
Span<byte> significantY = stackalloc byte[y!.GetSignificandByteCount()];
147-
x.WriteSignificandBigEndian(significantX);
148-
y.WriteSignificandBigEndian(significantY);
145+
// Leave the space for custom floating-point type that has variable significand length
149146

150-
return significantX.SequenceCompareTo(significantY);
147+
if (x!.GetSignificandBitLength() == y!.GetSignificandBitLength())
148+
{
149+
// Prevent stack overflow for huge numbers
150+
const int StackAllocThreshold = 256;
151+
152+
int xSignificandLength = x!.GetSignificandByteCount();
153+
int ySignificandLength = y!.GetSignificandByteCount();
154+
155+
Span<byte> significantX = xSignificandLength <= StackAllocThreshold ? stackalloc byte[xSignificandLength] : new byte[xSignificandLength];
156+
Span<byte> significantY = ySignificandLength <= StackAllocThreshold ? stackalloc byte[ySignificandLength] : new byte[ySignificandLength];
157+
158+
x.WriteSignificandBigEndian(significantX);
159+
y.WriteSignificandBigEndian(significantY);
160+
161+
return significantX.SequenceCompareTo(significantY);
162+
}
163+
else
164+
{
165+
return x.GetSignificandBitLength().CompareTo(y.GetSignificandBitLength());
166+
}
151167
}
152168

153169
if (T.IsNaN(x))

0 commit comments

Comments
 (0)