[codec,nsc] fix input length validation
This commit is contained in:
parent
60dd48e698
commit
cd1da25a87
@ -112,12 +112,17 @@ static BOOL nsc_decode(NSC_CONTEXT* context)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalSize)
|
||||
static BOOL nsc_rle_decode(const BYTE* in, size_t inSize, BYTE* out, UINT32 outSize,
|
||||
UINT32 originalSize)
|
||||
{
|
||||
UINT32 left = originalSize;
|
||||
|
||||
while (left > 4)
|
||||
{
|
||||
if (inSize < 1)
|
||||
return FALSE;
|
||||
inSize--;
|
||||
|
||||
const BYTE value = *in++;
|
||||
UINT32 len = 0;
|
||||
|
||||
@ -130,17 +135,26 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS
|
||||
*out++ = value;
|
||||
left--;
|
||||
}
|
||||
else if (inSize < 1)
|
||||
return FALSE;
|
||||
else if (value == *in)
|
||||
{
|
||||
inSize--;
|
||||
in++;
|
||||
|
||||
if (*in < 0xFF)
|
||||
if (inSize < 1)
|
||||
return FALSE;
|
||||
else if (*in < 0xFF)
|
||||
{
|
||||
inSize--;
|
||||
len = (UINT32)*in++;
|
||||
len += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inSize < 5)
|
||||
return FALSE;
|
||||
inSize -= 5;
|
||||
in++;
|
||||
len = ((UINT32)(*in++));
|
||||
len |= ((UINT32)(*in++)) << 8U;
|
||||
@ -170,6 +184,8 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS
|
||||
if ((outSize < 4) || (left < 4))
|
||||
return FALSE;
|
||||
|
||||
if (inSize < 4)
|
||||
return FALSE;
|
||||
memcpy(out, in, 4);
|
||||
return TRUE;
|
||||
}
|
||||
@ -179,7 +195,8 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
BYTE* rle = context->Planes;
|
||||
const BYTE* rle = context->Planes;
|
||||
size_t rleSize = context->PlanesSize;
|
||||
WINPR_ASSERT(rle);
|
||||
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
@ -187,6 +204,9 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
const UINT32 originalSize = context->OrgByteCount[i];
|
||||
const UINT32 planeSize = context->PlaneByteCount[i];
|
||||
|
||||
if (rleSize < planeSize)
|
||||
return FALSE;
|
||||
|
||||
if (planeSize == 0)
|
||||
{
|
||||
if (context->priv->PlaneBuffersLength < originalSize)
|
||||
@ -196,7 +216,7 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
}
|
||||
else if (planeSize < originalSize)
|
||||
{
|
||||
if (!nsc_rle_decode(rle, context->priv->PlaneBuffers[i],
|
||||
if (!nsc_rle_decode(rle, rleSize, context->priv->PlaneBuffers[i],
|
||||
context->priv->PlaneBuffersLength, originalSize))
|
||||
return FALSE;
|
||||
}
|
||||
@ -205,6 +225,9 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
if (context->priv->PlaneBuffersLength < originalSize)
|
||||
return FALSE;
|
||||
|
||||
if (rleSize < originalSize)
|
||||
return FALSE;
|
||||
|
||||
CopyMemory(context->priv->PlaneBuffers[i], rle, originalSize);
|
||||
}
|
||||
|
||||
@ -232,6 +255,7 @@ static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s)
|
||||
Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
||||
Stream_Seek(s, 2); /* Reserved (2 bytes) */
|
||||
context->Planes = Stream_Pointer(s);
|
||||
context->PlanesSize = total;
|
||||
return Stream_CheckAndLogRequiredLengthWLog(context->priv->log, s, total);
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ struct S_NSC_CONTEXT
|
||||
UINT32 BitmapDataLength;
|
||||
|
||||
BYTE* Planes;
|
||||
size_t PlanesSize;
|
||||
UINT32 PlaneByteCount[4];
|
||||
UINT32 ColorLossLevel;
|
||||
UINT32 ChromaSubsamplingLevel;
|
||||
|
Loading…
Reference in New Issue
Block a user