mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-07 17:29:36 +00:00
tier1: fix possible unsafe read in lzss SafeUncompress, make tests pass under asan
This commit is contained in:
+23
-21
@@ -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++;
|
||||
|
||||
Reference in New Issue
Block a user