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

Commit 07fd176

Browse files
tannergoodingwtgodbe
authored andcommitted
Merged PR 21063: Resolve MSRC 68613 for .NET Core 3.1
Resolve MSRC 68613 for .NET Core 3.1
1 parent d63dd78 commit 07fd176

File tree

1 file changed

+120
-16
lines changed

1 file changed

+120
-16
lines changed

src/System.Private.CoreLib/shared/System/Number.BigInteger.cs

Lines changed: 120 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -353,18 +353,33 @@ public static void Add(ref BigInteger lhs, uint value, ref BigInteger result)
353353
while (index < lhsLength)
354354
{
355355
ulong sum = (ulong)(lhs._blocks[index]) + carry;
356-
lhs._blocks[index] = (uint)(sum);
356+
result._blocks[index] = (uint)(sum);
357357
carry = (uint)(sum >> 32);
358358

359359
index++;
360360
}
361361

362+
int resultLength = lhsLength;
363+
362364
if (carry != 0)
363365
{
364-
Debug.Assert(unchecked((uint)(lhsLength)) + 1 <= MaxBlockCount);
366+
Debug.Assert(unchecked((uint)(resultLength)) < MaxBlockCount);
367+
368+
if (unchecked((uint)(resultLength)) >= MaxBlockCount)
369+
{
370+
// We shouldn't reach here, and the above assert will help flag this
371+
// during testing, but we'll ensure that we return a safe value of
372+
// zero in the case we end up overflowing in any way.
373+
374+
result.SetZero();
375+
return;
376+
}
377+
365378
result._blocks[index] = carry;
366-
result._length = (lhsLength + 1);
379+
resultLength += 1;
367380
}
381+
382+
result._length = resultLength;
368383
}
369384

370385
public static void Add(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result)
@@ -409,15 +424,30 @@ public static void Add(ref BigInteger lhs, ref BigInteger rhs, out BigInteger re
409424
resultIndex++;
410425
}
411426

427+
int resultLength = largeLength;
428+
412429
// If there's still a carry, append a new block
413430
if (carry != 0)
414431
{
415432
Debug.Assert(carry == 1);
416-
Debug.Assert((resultIndex == largeLength) && (largeLength < MaxBlockCount));
433+
Debug.Assert(resultIndex == resultLength);
434+
Debug.Assert(unchecked((uint)(resultLength)) < MaxBlockCount);
435+
436+
if (unchecked((uint)(resultLength)) >= MaxBlockCount)
437+
{
438+
// We shouldn't reach here, and the above assert will help flag this
439+
// during testing, but we'll ensure that we return a safe value of
440+
// zero in the case we end up overflowing in any way.
441+
442+
result.SetZero();
443+
return;
444+
}
417445

418446
result._blocks[resultIndex] = 1;
419-
result._length += 1;
447+
resultLength += 1;
420448
}
449+
450+
result._length = resultLength;
421451
}
422452

423453
public static int Compare(ref BigInteger lhs, ref BigInteger rhs)
@@ -765,12 +795,27 @@ public static void Multiply(ref BigInteger lhs, uint value, ref BigInteger resul
765795
index++;
766796
}
767797

798+
int resultLength = lhsLength;
799+
768800
if (carry != 0)
769801
{
770-
Debug.Assert(unchecked((uint)(lhsLength)) + 1 <= MaxBlockCount);
802+
Debug.Assert(unchecked((uint)(resultLength)) < MaxBlockCount);
803+
804+
if (unchecked((uint)(resultLength)) >= MaxBlockCount)
805+
{
806+
// We shouldn't reach here, and the above assert will help flag this
807+
// during testing, but we'll ensure that we return a safe value of
808+
// zero in the case we end up overflowing in any way.
809+
810+
result.SetZero();
811+
return;
812+
}
813+
771814
result._blocks[index] = carry;
772-
result._length = (lhsLength + 1);
815+
resultLength += 1;
773816
}
817+
818+
result._length = resultLength;
774819
}
775820

776821
public static void Multiply(ref BigInteger lhs, ref BigInteger rhs, ref BigInteger result)
@@ -804,6 +849,16 @@ public static void Multiply(ref BigInteger lhs, ref BigInteger rhs, ref BigInteg
804849

805850
int maxResultLength = smallLength + largeLength;
806851
Debug.Assert(unchecked((uint)(maxResultLength)) <= MaxBlockCount);
852+
853+
if (unchecked((uint)(maxResultLength)) > MaxBlockCount)
854+
{
855+
// We shouldn't reach here, and the above assert will help flag this
856+
// during testing, but we'll ensure that we return a safe value of
857+
// zero in the case we end up overflowing in any way.
858+
859+
result.SetZero();
860+
return;
861+
}
807862

808863
// Zero out result internal blocks.
809864
Buffer.ZeroMemory((byte*)(result.GetBlocksPointer()), (maxResultLength * sizeof(uint)));
@@ -1072,6 +1127,18 @@ public void ExtendBlock(uint blockValue)
10721127
{
10731128
_blocks[_length] = blockValue;
10741129
_length++;
1130+
1131+
Debug.Assert(unchecked((uint)(_length)) <= MaxBlockCount);
1132+
1133+
if (unchecked((uint)(_length)) > MaxBlockCount)
1134+
{
1135+
// We shouldn't reach here, and the above assert will help flag this
1136+
// during testing, but we'll ensure that we return a safe value of
1137+
// zero in the case we end up overflowing in any way.
1138+
1139+
SetZero();
1140+
return;
1141+
}
10751142
}
10761143

10771144
public void ExtendBlocks(uint blockValue, uint blockCount)
@@ -1081,7 +1148,19 @@ public void ExtendBlocks(uint blockValue, uint blockCount)
10811148
if (blockCount == 1)
10821149
{
10831150
ExtendBlock(blockValue);
1151+
return;
1152+
}
10841153

1154+
int resultLength = _length + (int)(blockCount);
1155+
Debug.Assert(unchecked((uint)(resultLength)) <= MaxBlockCount);
1156+
1157+
if (unchecked((uint)(resultLength)) > MaxBlockCount)
1158+
{
1159+
// We shouldn't reach here, and the above assert will help flag this
1160+
// during testing, but we'll ensure that we return a safe value of
1161+
// zero in the case we end up overflowing in any way.
1162+
1163+
SetZero();
10851164
return;
10861165
}
10871166

@@ -1149,9 +1228,20 @@ public void Multiply10()
11491228

11501229
if (carry != 0)
11511230
{
1152-
Debug.Assert(unchecked((uint)(_length)) + 1 <= MaxBlockCount);
1231+
Debug.Assert(unchecked((uint)(length)) < MaxBlockCount);
1232+
1233+
if (unchecked((uint)(length)) >= MaxBlockCount)
1234+
{
1235+
// We shouldn't reach here, and the above assert will help flag this
1236+
// during testing, but we'll ensure that we return a safe value of
1237+
// zero in the case we end up overflowing in any way.
1238+
1239+
SetZero();
1240+
return;
1241+
}
1242+
11531243
_blocks[index] = (uint)(carry);
1154-
_length += 1;
1244+
_length = length + 1;
11551245
}
11561246
}
11571247

@@ -1214,11 +1304,29 @@ public void ShiftLeft(uint shift)
12141304
int readIndex = (length - 1);
12151305
int writeIndex = readIndex + (int)(blocksToShift);
12161306

1307+
uint remainingBitsInLastBlock = (uint)BitOperations.LeadingZeroCount(_blocks[readIndex]);
1308+
1309+
if (remainingBitsToShift > remainingBitsInLastBlock)
1310+
{
1311+
// We need an extra block for the partial shift
1312+
writeIndex++;
1313+
}
1314+
1315+
Debug.Assert(unchecked((uint)(writeIndex)) < MaxBlockCount);
1316+
1317+
if (unchecked((uint)(writeIndex)) >= MaxBlockCount)
1318+
{
1319+
// We shouldn't reach here, and the above assert will help flag this
1320+
// during testing, but we'll ensure that we return a safe value of
1321+
// zero in the case we end up overflowing in any way.
1322+
1323+
SetZero();
1324+
return;
1325+
}
1326+
12171327
// Check if the shift is block aligned
12181328
if (remainingBitsToShift == 0)
12191329
{
1220-
Debug.Assert(writeIndex < MaxBlockCount);
1221-
12221330
while (readIndex >= 0)
12231331
{
12241332
_blocks[writeIndex] = _blocks[readIndex];
@@ -1232,11 +1340,7 @@ public void ShiftLeft(uint shift)
12321340
Buffer.ZeroMemory((byte*)(GetBlocksPointer()), (blocksToShift * sizeof(uint)));
12331341
}
12341342
else
1235-
{
1236-
// We need an extra block for the partial shift
1237-
writeIndex++;
1238-
Debug.Assert(writeIndex < MaxBlockCount);
1239-
1343+
{
12401344
// Set the length to hold the shifted blocks
12411345
_length = writeIndex + 1;
12421346

0 commit comments

Comments
 (0)