@@ -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
400403bool 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