Fixed #4954: Check destination buffer bounds.

This commit is contained in:
Armin Novak
2018-10-23 10:33:45 +02:00
parent 76c91ee51a
commit 10d3ee131e
2 changed files with 216 additions and 68 deletions

View File

@@ -24,7 +24,7 @@
/**
* Write a foreground/background image to a destination buffer.
*/
static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd, UINT32 rowDelta,
BYTE bitmask, PIXEL fgPel, INT32 cBits)
{
PIXEL xorPixel;
@@ -32,11 +32,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
if (bitmask & g_MaskBit0)
{
DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, xorPixel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -48,11 +50,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
if (bitmask & g_MaskBit1)
{
DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, xorPixel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -64,11 +68,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
if (bitmask & g_MaskBit2)
{
DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, xorPixel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -80,11 +86,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
if (bitmask & g_MaskBit3)
{
DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, xorPixel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -96,11 +104,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
if (bitmask & g_MaskBit4)
{
DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, xorPixel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -112,11 +122,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
if (bitmask & g_MaskBit5)
{
DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, xorPixel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -128,11 +140,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
if (bitmask & g_MaskBit6)
{
DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, xorPixel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -144,11 +158,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
if (bitmask & g_MaskBit7)
{
DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, xorPixel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -167,16 +183,18 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta,
* Write a foreground/background image to a destination buffer
* for the first line of compressed data.
*/
static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask,
static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd, BYTE bitmask,
PIXEL fgPel, UINT32 cBits)
{
if (bitmask & g_MaskBit0)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -186,11 +204,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask,
{
if (bitmask & g_MaskBit1)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -200,11 +220,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask,
{
if (bitmask & g_MaskBit2)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -214,11 +236,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask,
{
if (bitmask & g_MaskBit3)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -228,11 +252,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask,
{
if (bitmask & g_MaskBit4)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -242,11 +268,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask,
{
if (bitmask & g_MaskBit5)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -256,11 +284,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask,
{
if (bitmask & g_MaskBit6)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -270,11 +300,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask,
{
if (bitmask & g_MaskBit7)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return NULL;
}
else
{
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return NULL;
}
DESTNEXTPIXEL(pbDest);
@@ -298,6 +330,7 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
{
const BYTE* pbSrc = pbSrcBuffer;
const BYTE* pbEnd = pbSrcBuffer + cbSrcBuffer;
const BYTE* pbDestEnd = pbDestBuffer + rowDelta * height;
BYTE* pbDest = pbDestBuffer;
PIXEL temp;
PIXEL fgPel = WHITE_PIXEL;
@@ -310,6 +343,9 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
UINT32 advance;
RLEEXTRA
if ((rowDelta == 0) || (rowDelta < width))
return FALSE;
if (!pbSrcBuffer || !pbDestBuffer)
return FALSE;
@@ -341,7 +377,9 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
{
if (fInsertFgPel)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return FALSE;
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
@@ -349,14 +387,19 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return FALSE;
DESTNEXTPIXEL(pbDest););
runLength = runLength - UNROLL_COUNT;
}
while (runLength > 0)
{
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return FALSE;
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
@@ -366,7 +409,10 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
if (fInsertFgPel)
{
DESTREADPIXEL(temp, pbDest - rowDelta);
DESTWRITEPIXEL(pbDest, temp ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp ^ fgPel))
return FALSE;
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
@@ -375,15 +421,21 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
{
UNROLL(
DESTREADPIXEL(temp, pbDest - rowDelta);
DESTWRITEPIXEL(pbDest, temp);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp))
return FALSE;
DESTNEXTPIXEL(pbDest););
runLength = runLength - UNROLL_COUNT;
}
while (runLength > 0)
{
DESTREADPIXEL(temp, pbDest - rowDelta);
DESTWRITEPIXEL(pbDest, temp);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp))
return FALSE;
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
@@ -419,14 +471,19 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return FALSE;
DESTNEXTPIXEL(pbDest););
runLength = runLength - UNROLL_COUNT;
}
while (runLength > 0)
{
DESTWRITEPIXEL(pbDest, fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel))
return FALSE;
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
@@ -437,15 +494,21 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
{
UNROLL(
DESTREADPIXEL(temp, pbDest - rowDelta);
DESTWRITEPIXEL(pbDest, temp ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp ^ fgPel))
return FALSE;
DESTNEXTPIXEL(pbDest););
runLength = runLength - UNROLL_COUNT;
}
while (runLength > 0)
{
DESTREADPIXEL(temp, pbDest - rowDelta);
DESTWRITEPIXEL(pbDest, temp ^ fgPel);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp ^ fgPel))
return FALSE;
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
@@ -466,18 +529,27 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTWRITEPIXEL(pbDest, pixelA);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelA))
return FALSE;
DESTNEXTPIXEL(pbDest);
DESTWRITEPIXEL(pbDest, pixelB);
DESTNEXTPIXEL(pbDest););
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelB))
return FALSE;
DESTNEXTPIXEL(pbDest););
runLength = runLength - UNROLL_COUNT;
}
while (runLength > 0)
{
DESTWRITEPIXEL(pbDest, pixelA);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelA))
return FALSE;
DESTNEXTPIXEL(pbDest);
DESTWRITEPIXEL(pbDest, pixelB);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelB))
return FALSE;
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
@@ -495,14 +567,19 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
while (runLength >= UNROLL_COUNT)
{
UNROLL(
DESTWRITEPIXEL(pbDest, pixelA);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelA))
return FALSE;
DESTNEXTPIXEL(pbDest););
runLength = runLength - UNROLL_COUNT;
}
while (runLength > 0)
{
DESTWRITEPIXEL(pbDest, pixelA);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelA))
return FALSE;
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
@@ -529,7 +606,11 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
{
bitmask = *pbSrc;
pbSrc = pbSrc + 1;
pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, bitmask, fgPel, 8);
pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
if (!pbDest)
return FALSE;
runLength = runLength - 8;
}
}
@@ -539,7 +620,11 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
{
bitmask = *pbSrc;
pbSrc = pbSrc + 1;
pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, bitmask, fgPel, 8);
pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
if (!pbDest)
return FALSE;
runLength = runLength - 8;
}
}
@@ -551,12 +636,15 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
if (fFirstLine)
{
pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, bitmask, fgPel, runLength);
pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
}
else
{
pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, bitmask, fgPel, runLength);
pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
}
if (!pbDest)
return FALSE;
}
break;
@@ -572,8 +660,11 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
UNROLL(
SRCREADPIXEL(temp, pbSrc);
SRCNEXTPIXEL(pbSrc);
DESTWRITEPIXEL(pbDest, temp);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp))
return FALSE;
DESTNEXTPIXEL(pbDest););
runLength = runLength - UNROLL_COUNT;
}
@@ -581,7 +672,10 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
{
SRCREADPIXEL(temp, pbSrc);
SRCNEXTPIXEL(pbSrc);
DESTWRITEPIXEL(pbDest, temp);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp))
return FALSE;
DESTNEXTPIXEL(pbDest);
runLength = runLength - 1;
}
@@ -594,13 +688,16 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
if (fFirstLine)
{
pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, g_MaskSpecialFgBg1, fgPel, 8);
pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
}
else
{
pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
}
if (!pbDest)
return FALSE;
break;
/* Handle Special Order 2. */
@@ -609,26 +706,35 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer,
if (fFirstLine)
{
pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, g_MaskSpecialFgBg2, fgPel, 8);
pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
}
else
{
pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
}
if (!pbDest)
return FALSE;
break;
/* Handle White Order. */
case SPECIAL_WHITE:
pbSrc = pbSrc + 1;
DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, WHITE_PIXEL))
return FALSE;
DESTNEXTPIXEL(pbDest);
break;
/* Handle Black Order. */
case SPECIAL_BLACK:
pbSrc = pbSrc + 1;
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL))
return FALSE;
DESTNEXTPIXEL(pbDest);
break;