tier1: fix possible unsafe read in lzss SafeUncompress, make tests pass under asan

This commit is contained in:
nillerusr
2023-04-07 14:59:36 +03:00
parent 4f063c4053
commit 92028d4e80
7 changed files with 115 additions and 25 deletions
+23 -21
View File
@@ -294,59 +294,61 @@ unsigned int CLZSS::Uncompress( unsigned char *pInput, CUtlBuffer &buf )
}
*/
unsigned int CLZSS::SafeUncompress( const unsigned char *pInput, unsigned char *pOutput, unsigned int unBufSize )
unsigned int CLZSS::SafeUncompress( const unsigned char *pInput, unsigned int inputSize, unsigned char *pOutput, unsigned int unBufSize )
{
unsigned int totalBytes = 0;
int cmdByte = 0;
int getCmdByte = 0;
unsigned int actualSize = GetActualSize( pInput );
if ( !actualSize )
{
// unrecognized
return 0;
}
if ( actualSize > unBufSize )
{
if ( !actualSize ||
actualSize > unBufSize ||
inputSize <= sizeof( lzss_header_t ) )
return 0;
}
const unsigned char *pInputEnd = pInput+inputSize-1;
const unsigned char *pOrigOutput = pOutput;
pInput += sizeof( lzss_header_t );
for ( ;; )
{
if ( !getCmdByte )
if ( !getCmdByte )
{
if( pInput > pInputEnd )
return 0;
cmdByte = *pInput++;
}
getCmdByte = ( getCmdByte + 1 ) & 0x07;
if ( cmdByte & 0x01 )
{
if( pInput+1 > pInputEnd )
return 0;
int position = *pInput++ << LZSS_LOOKSHIFT;
position |= ( *pInput >> LZSS_LOOKSHIFT );
int count = ( *pInput++ & 0x0F ) + 1;
if ( count == 1 )
{
if ( count == 1 )
break;
}
unsigned char *pSource = pOutput - position - 1;
if ( totalBytes + count > unBufSize )
{
if ( totalBytes + count > unBufSize ||
pSource < pOrigOutput )
return 0;
}
for ( int i=0; i<count; i++ )
{
*pOutput++ = *pSource++;
}
totalBytes += count;
}
else
}
else
{
if ( totalBytes + 1 > unBufSize )
if ( totalBytes + 1 > unBufSize ||
pInput > pInputEnd )
return 0;
*pOutput++ = *pInput++;