Skip to content

Commit 074a5fd

Browse files
committed
Stricter checks, defensive coding
1 parent 815b00d commit 074a5fd

1 file changed

Lines changed: 17 additions & 4 deletions

File tree

src/transform/ROLZCodec.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ bool ROLZCodec::inverse(SliceArray<byte>& input, SliceArray<byte>& output, int c
8585
if (input._array == output._array)
8686
return false;
8787

88+
if ((count < 5) || (input._index + count > input._length))
89+
return false;
90+
8891
if (count > MAX_BLOCK_SIZE)
8992
return false;
9093

@@ -393,14 +396,13 @@ bool ROLZCodec1::forward(SliceArray<byte>& input, SliceArray<byte>& output, int
393396
delete[] lenBuf._array;
394397
delete[] mIdxBuf._array;
395398
delete[] tkBuf._array;
396-
return (input._index == count) && (output._index < count);
399+
return (input._index == count) && (dstIdx < count);
397400
}
398401

399402

400403
bool ROLZCodec1::inverse(SliceArray<byte>& input, SliceArray<byte>& output, int count)
401404
{
402405
byte* src = &input._array[input._index];
403-
byte* dst = &output._array[output._index];
404406
const int end = BigEndian::readInt32(&src[0]);
405407

406408
if ((end <= 4) || (end - 4 > output._length - output._index))
@@ -467,6 +469,7 @@ bool ROLZCodec1::inverse(SliceArray<byte>& input, SliceArray<byte>& output, int
467469
const int endChunk = min(startChunk + sizeChunk, dstEnd);
468470
sizeChunk = endChunk - startChunk;
469471
bool onlyLiterals = false;
472+
int litLenDecoded = 0;
470473

471474
try
472475
{
@@ -478,6 +481,7 @@ bool ROLZCodec1::inverse(SliceArray<byte>& input, SliceArray<byte>& output, int
478481
const int tkLen = int(ibs.readBits(32));
479482
const int mLenLen = int(ibs.readBits(32));
480483
const int mIdxLen = int(ibs.readBits(32));
484+
const int firstLitLen = min(sizeChunk, 8);
481485

482486
if ((litLen < 0) || (tkLen < 0) || (mLenLen < 0) || (mIdxLen < 0)) {
483487
input._index += srcIdx;
@@ -486,13 +490,17 @@ bool ROLZCodec1::inverse(SliceArray<byte>& input, SliceArray<byte>& output, int
486490
goto End;
487491
}
488492

489-
if ((litLen > litBuf._length) || (tkLen > tkBuf._length) || (mLenLen > lenBuf._length) || (mIdxLen > mIdxBuf._length)) {
493+
if ((litLen > litBuf._length) || (tkLen > tkBuf._length) || (mLenLen > lenBuf._length) ||
494+
(mIdxLen > mIdxBuf._length) || (litLen < firstLitLen) || (litLen > sizeChunk) ||
495+
((tkLen == 0) && (mIdxLen != 0)) || ((tkLen > 0) && (mIdxLen + 1 != tkLen))) {
490496
input._index += srcIdx;
491497
output._index += startChunk;
492498
success = false;
493499
goto End;
494500
}
495501

502+
litLenDecoded = litLen;
503+
496504
ANSRangeDecoder litDec(ibs, litOrder);
497505
litDec.decode(litBuf._array, 0, litLen);
498506
litDec.dispose();
@@ -512,6 +520,11 @@ bool ROLZCodec1::inverse(SliceArray<byte>& input, SliceArray<byte>& output, int
512520

513521
if (onlyLiterals == true) {
514522
// Shortcut when no match
523+
if (litLenDecoded != sizeChunk) {
524+
success = false;
525+
goto End;
526+
}
527+
515528
memcpy(&output._array[output._index], &litBuf._array[0], size_t(sizeChunk));
516529
startChunk = endChunk;
517530
output._index += sizeChunk;
@@ -609,7 +622,7 @@ bool ROLZCodec1::inverse(SliceArray<byte>& input, SliceArray<byte>& output, int
609622
success = false;
610623
}
611624
else {
612-
memcpy(&dst[output._index], &src[srcIdx], 4);
625+
memcpy(&output._array[output._index], &src[srcIdx], 4);
613626
output._index += 4;
614627
srcIdx += 4;
615628
}

0 commit comments

Comments
 (0)