Bug 83804 - crash in gif decoder caused by mismatch in rgb line buffer size.

Moved ownership of rgb line buffer to nsGIFDecoder2.
r=pavlov, sr=blizzard, a=blizzard
This commit is contained in:
tor%cs.brown.edu 2001-06-04 22:24:38 +00:00
Родитель 4dde2c3cec
Коммит 4eaa263d05
4 изменённых файлов: 15 добавлений и 24 удалений

Просмотреть файл

@ -198,7 +198,6 @@ output_row(gif_struct *gs)
int result = (gs->GIFCallback_HaveDecodedRow)( int result = (gs->GIFCallback_HaveDecodedRow)(
gs->clientptr, gs->clientptr,
gs->rowbuf, /* Pointer to single scanline temporary buffer */ gs->rowbuf, /* Pointer to single scanline temporary buffer */
gs->rgbrow, /* Pointer to temporary storage for dithering/mapping */
gs->x_offset, /* x offset with respect to GIF logical screen origin */ gs->x_offset, /* x offset with respect to GIF logical screen origin */
width, /* Length of the row */ width, /* Length of the row */
drow_start, /* Row number */ drow_start, /* Row number */
@ -478,7 +477,6 @@ PRBool GIFInit(
int (*PR_CALLBACK GIFCallback_HaveDecodedRow)( int (*PR_CALLBACK GIFCallback_HaveDecodedRow)(
void* aClientData, void* aClientData,
PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */ PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */
PRUint8* aRGBrowBufPtr,/* Pointer to temporary storage for dithering/mapping */
int aXOffset, /* With respect to GIF logical screen origin */ int aXOffset, /* With respect to GIF logical screen origin */
int aLength, /* Length of the row? */ int aLength, /* Length of the row? */
int aRow, /* Row number? */ int aRow, /* Row number? */
@ -1260,11 +1258,9 @@ int gif_write(gif_struct *gs, const PRUint8 *buf, PRUint32 len)
if (gs->screen_width < width) { if (gs->screen_width < width) {
/* XXX Deviant! */ /* XXX Deviant! */
//gs->rgbrow = (PRUint8*)PR_REALLOC(gs->rgbrow, 3 * width);
gs->rgbrow = (PRUint8*)PR_REALLOC(gs->rgbrow, sizeof(GIF_RGB) * width);
gs->rowbuf = (PRUint8*)PR_REALLOC(gs->rowbuf, width); gs->rowbuf = (PRUint8*)PR_REALLOC(gs->rowbuf, width);
if((!gs->rgbrow)||(!gs->rowbuf)){ if(!gs->rowbuf){
gs->state = gif_oom; gs->state = gif_oom;
break; break;
} }
@ -1300,15 +1296,11 @@ int gif_write(gif_struct *gs, const PRUint8 *buf, PRUint32 len)
//} //}
} }
else{ else{
if (!gs->rgbrow)
gs->rgbrow = (PRUint8*)PR_MALLOC(sizeof(GIF_RGB) * gs->screen_width);
//gs->rgbrow = (PRUint8*)PR_MALLOC(3 * gs->screen_width);
if (!gs->rowbuf) if (!gs->rowbuf)
gs->rowbuf = (PRUint8*)PR_MALLOC(gs->screen_width); gs->rowbuf = (PRUint8*)PR_MALLOC(gs->screen_width);
} }
if (!gs->rowbuf || !gs->rgbrow) if (!gs->rowbuf)
{ {
//ILTRACE(0,("il:gif: MEM row")); //ILTRACE(0,("il:gif: MEM row"));
gs->state=gif_oom; gs->state=gif_oom;
@ -1674,7 +1666,6 @@ gif_destroy(gif_struct *gs)
gif_destroy_transparency(gs); gif_destroy_transparency(gs);
PR_FREEIF(gs->rowbuf); PR_FREEIF(gs->rowbuf);
PR_FREEIF(gs->rgbrow);
PR_FREEIF(gs->prefix); PR_FREEIF(gs->prefix);
PR_FREEIF(gs->suffix); PR_FREEIF(gs->suffix);
PR_FREEIF(gs->stack); PR_FREEIF(gs->stack);

Просмотреть файл

@ -131,7 +131,6 @@ typedef struct gif_struct {
int (PR_CALLBACK* GIFCallback_HaveDecodedRow)( int (PR_CALLBACK* GIFCallback_HaveDecodedRow)(
void* aClientData, void* aClientData,
PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */ PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */
PRUint8* aRGBrowBufPtr,/* Pointer to temporary storage for dithering/mapping */
int aXOffset, /* With respect to GIF logical screen origin */ int aXOffset, /* With respect to GIF logical screen origin */
int aLength, /* Length of the row? */ int aLength, /* Length of the row? */
int aRow, /* Row number? */ int aRow, /* Row number? */
@ -171,7 +170,6 @@ typedef struct gif_struct {
int ipass; /* Interlace pass; Ranges 1-4 if interlaced. */ int ipass; /* Interlace pass; Ranges 1-4 if interlaced. */
PRUintn rows_remaining; /* Rows remaining to be output */ PRUintn rows_remaining; /* Rows remaining to be output */
PRUintn irow; /* Current output row, starting at zero */ PRUintn irow; /* Current output row, starting at zero */
PRUint8 *rgbrow; /* Temporary storage for dithering/mapping */
PRUint8 *rowbuf; /* Single scanline temporary buffer */ PRUint8 *rowbuf; /* Single scanline temporary buffer */
PRUint8 *rowend; /* Pointer to end of rowbuf */ PRUint8 *rowend; /* Pointer to end of rowbuf */
PRUint8 *rowp; /* Current output pointer */ PRUint8 *rowp; /* Current output pointer */
@ -257,7 +255,6 @@ PRBool GIFInit(
int (*PR_CALLBACK GIFCallback_HaveDecodedRow)( int (*PR_CALLBACK GIFCallback_HaveDecodedRow)(
void* aClientData, void* aClientData,
PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */ PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */
PRUint8* aRGBrowBufPtr,/* Pointer to temporary storage for dithering/mapping */
int aXOffset, /* With respect to GIF logical screen origin */ int aXOffset, /* With respect to GIF logical screen origin */
int aLength, /* Length of the row? */ int aLength, /* Length of the row? */
int aRow, /* Row number? */ int aRow, /* Row number? */

Просмотреть файл

@ -45,6 +45,7 @@ nsGIFDecoder2::nsGIFDecoder2()
mGIFStruct = nsnull; mGIFStruct = nsnull;
mAlphaLine = nsnull; mAlphaLine = nsnull;
mRGBLine = nsnull;
mBackgroundRGBIndex = 0; mBackgroundRGBIndex = 0;
mCurrentRow = -1; mCurrentRow = -1;
@ -59,6 +60,9 @@ nsGIFDecoder2::~nsGIFDecoder2(void)
if (mAlphaLine) if (mAlphaLine)
nsMemory::Free(mAlphaLine); nsMemory::Free(mAlphaLine);
if (mRGBLine)
nsMemory::Free(mRGBLine);
if (mGIFStruct) { if (mGIFStruct) {
gif_destroy(mGIFStruct); gif_destroy(mGIFStruct);
mGIFStruct = nsnull; mGIFStruct = nsnull;
@ -378,7 +382,6 @@ int HaveImageAll(
int HaveDecodedRow( int HaveDecodedRow(
void* aClientData, void* aClientData,
PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer
PRUint8* aRGBrowBufPtr,// Pointer to temporary storage for dithering/mapping
int aXOffset, // With respect to GIF logical screen origin int aXOffset, // With respect to GIF logical screen origin
int aLength, // Length of the row? int aLength, // Length of the row?
int aRowNumber, // Row number? int aRowNumber, // Row number?
@ -418,10 +421,10 @@ int HaveDecodedRow(
decoder->mImageFrame->GetImageBytesPerRow(&bpr); decoder->mImageFrame->GetImageBytesPerRow(&bpr);
decoder->mImageFrame->GetAlphaBytesPerRow(&abpr); decoder->mImageFrame->GetAlphaBytesPerRow(&abpr);
decoder->mRGBLine = (PRUint8 *)nsMemory::Realloc(decoder->mRGBLine, bpr);
if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) { if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
if (decoder->mAlphaLine) decoder->mAlphaLine = (PRUint8 *)nsMemory::Realloc(decoder->mAlphaLine, abpr);
nsMemory::Free(decoder->mAlphaLine);
decoder->mAlphaLine = (PRUint8 *)nsMemory::Alloc(abpr);
} }
} else { } else {
decoder->mImageFrame->GetImageBytesPerRow(&bpr); decoder->mImageFrame->GetImageBytesPerRow(&bpr);
@ -456,7 +459,7 @@ int HaveDecodedRow(
cmap = decoder->mGIFStruct->local_colormap; cmap = decoder->mGIFStruct->local_colormap;
} }
PRUint8* rgbRowIndex = aRGBrowBufPtr; PRUint8* rgbRowIndex = decoder->mRGBLine;
PRUint8* rowBufIndex = aRowBufPtr; PRUint8* rowBufIndex = aRowBufPtr;
switch (format) { switch (format) {
@ -473,7 +476,7 @@ int HaveDecodedRow(
} }
for (int i=0; i<aDuplicateCount; i++) for (int i=0; i<aDuplicateCount; i++)
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, decoder->mImageFrame->SetImageData(decoder->mRGBLine,
bpr, (aRowNumber+i)*bpr); bpr, (aRowNumber+i)*bpr);
} }
break; break;
@ -487,7 +490,7 @@ int HaveDecodedRow(
} }
for (int i=0; i<aDuplicateCount; i++) for (int i=0; i<aDuplicateCount; i++)
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, decoder->mImageFrame->SetImageData(decoder->mRGBLine,
bpr, (aRowNumber+i)*bpr); bpr, (aRowNumber+i)*bpr);
} }
break; break;
@ -502,7 +505,7 @@ int HaveDecodedRow(
decoder->mImageFrame->SetTransparentColor(transColor); decoder->mImageFrame->SetTransparentColor(transColor);
} }
memset(aRGBrowBufPtr, 0, bpr); memset(decoder->mRGBLine, 0, bpr);
memset(decoder->mAlphaLine, 0, abpr); memset(decoder->mAlphaLine, 0, abpr);
PRUint32 iwidth = (PRUint32)width; PRUint32 iwidth = (PRUint32)width;
for (PRUint32 x=0; x<iwidth; x++) { for (PRUint32 x=0; x<iwidth; x++) {
@ -531,7 +534,7 @@ int HaveDecodedRow(
++rowBufIndex; ++rowBufIndex;
} }
for (int i=0; i<aDuplicateCount; i++) { for (int i=0; i<aDuplicateCount; i++) {
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, decoder->mImageFrame->SetImageData(decoder->mRGBLine,
bpr, (aRowNumber+i)*bpr); bpr, (aRowNumber+i)*bpr);
decoder->mImageFrame->SetAlphaData(decoder->mAlphaLine, decoder->mImageFrame->SetAlphaData(decoder->mAlphaLine,
abpr, (aRowNumber+i)*abpr); abpr, (aRowNumber+i)*abpr);

Просмотреть файл

@ -70,6 +70,7 @@ public:
gif_struct *mGIFStruct; gif_struct *mGIFStruct;
PRUint8 *mAlphaLine; PRUint8 *mAlphaLine;
PRUint8 *mRGBLine;
PRUint8 mBackgroundRGBIndex; PRUint8 mBackgroundRGBIndex;
PRUint8 mCurrentPass; PRUint8 mCurrentPass;
PRUint8 mLastFlushedPass; PRUint8 mLastFlushedPass;
@ -85,7 +86,6 @@ static int PR_CALLBACK BeginGIF(
static int PR_CALLBACK HaveDecodedRow( static int PR_CALLBACK HaveDecodedRow(
void* aClientData, void* aClientData,
PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer
PRUint8* aRGBrowBufPtr,// Pointer to temporary storage for dithering/mapping
int aXOffset, // With respect to GIF logical screen origin int aXOffset, // With respect to GIF logical screen origin
int aLength, // Length of the row? int aLength, // Length of the row?
int aRow, // Row number? int aRow, // Row number?