Bug 710079 - ICO files that contain PNG would end in some uninitialized memory. r=joe. a=joe

This commit is contained in:
Brian R. Bondy 2011-12-13 18:15:28 -05:00
parent 2adc6acc0a
commit 219f5b33ab
5 changed files with 28 additions and 25 deletions

View File

@ -174,8 +174,9 @@ NS_IMETHODIMP nsBMPEncoder::StartImageEncode(PRUint32 aWidth,
return NS_OK;
}
// Returns the image buffer size
NS_IMETHODIMP nsBMPEncoder::GetImageBufferSize(PRUint32 *aOutputSize)
// Returns the number of bytes in the image buffer used.
// For a BMP file, this is all bytes in the buffer.
NS_IMETHODIMP nsBMPEncoder::GetImageBufferUsed(PRUint32 *aOutputSize)
{
NS_ENSURE_ARG_POINTER(aOutputSize);
*aOutputSize = mImageBufferSize;

View File

@ -111,9 +111,10 @@ NS_IMETHODIMP nsICOEncoder::InitFromData(const PRUint8* aData,
return rv;
}
// Returns the image buffer size
// Returns the number of bytes in the image buffer used
// For an ICO file, this is all bytes in the buffer.
NS_IMETHODIMP
nsICOEncoder::GetImageBufferSize(PRUint32 *aOutputSize)
nsICOEncoder::GetImageBufferUsed(PRUint32 *aOutputSize)
{
NS_ENSURE_ARG_POINTER(aOutputSize);
*aOutputSize = mImageBufferSize;
@ -147,16 +148,16 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
aStride, aInputFormat, noParams);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 imageBufferSize;
mContainedEncoder->GetImageBufferSize(&imageBufferSize);
PRUint32 PNGImageBufferSize;
mContainedEncoder->GetImageBufferUsed(&PNGImageBufferSize);
mImageBufferSize = ICONFILEHEADERSIZE + ICODIRENTRYSIZE +
imageBufferSize;
PNGImageBufferSize;
mImageBufferStart = static_cast<PRUint8*>(moz_malloc(mImageBufferSize));
if (!mImageBufferStart) {
return NS_ERROR_OUT_OF_MEMORY;
}
mImageBufferCurr = mImageBufferStart;
mICODirEntry.mBytesInRes = imageBufferSize;
mICODirEntry.mBytesInRes = PNGImageBufferSize;
EncodeFileHeader();
EncodeInfoHeader();
@ -164,8 +165,8 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
char *imageBuffer;
rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
NS_ENSURE_SUCCESS(rv, rv);
memcpy(mImageBufferCurr, imageBuffer, imageBufferSize);
mImageBufferCurr += imageBufferSize;
memcpy(mImageBufferCurr, imageBuffer, PNGImageBufferSize);
mImageBufferCurr += PNGImageBufferSize;
} else {
mContainedEncoder = new nsBMPEncoder();
nsresult rv;
@ -181,10 +182,10 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
PRUint32 andMaskSize = ((GetRealWidth() + 31) / 32) * 4 * // row AND mask
GetRealHeight(); // num rows
PRUint32 imageBufferSize;
mContainedEncoder->GetImageBufferSize(&imageBufferSize);
PRUint32 BMPImageBufferSize;
mContainedEncoder->GetImageBufferUsed(&BMPImageBufferSize);
mImageBufferSize = ICONFILEHEADERSIZE + ICODIRENTRYSIZE +
imageBufferSize + andMaskSize;
BMPImageBufferSize + andMaskSize;
mImageBufferStart = static_cast<PRUint8*>(moz_malloc(mImageBufferSize));
if (!mImageBufferStart) {
return NS_ERROR_OUT_OF_MEMORY;
@ -192,7 +193,7 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
mImageBufferCurr = mImageBufferStart;
// The icon buffer does not include the BFH at all.
mICODirEntry.mBytesInRes = imageBufferSize - BFH_LENGTH + andMaskSize;
mICODirEntry.mBytesInRes = BMPImageBufferSize - BFH_LENGTH + andMaskSize;
// Encode the icon headers
EncodeFileHeader();
@ -202,13 +203,13 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
NS_ENSURE_SUCCESS(rv, rv);
memcpy(mImageBufferCurr, imageBuffer + BFH_LENGTH,
imageBufferSize - BFH_LENGTH);
BMPImageBufferSize - BFH_LENGTH);
// We need to fix the BMP height to be *2 for the AND mask
PRUint32 fixedHeight = GetRealHeight() * 2;
fixedHeight = NATIVE32_TO_LITTLE(fixedHeight);
// The height is stored at an offset of 8 from the DIB header
memcpy(mImageBufferCurr + 8, &fixedHeight, sizeof(fixedHeight));
mImageBufferCurr += imageBufferSize - BFH_LENGTH;
mImageBufferCurr += BMPImageBufferSize - BFH_LENGTH;
// Calculate rowsize in DWORD's
PRUint32 rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up

View File

@ -221,11 +221,11 @@ NS_IMETHODIMP nsJPEGEncoder::StartImageEncode(PRUint32 aWidth,
return NS_ERROR_NOT_IMPLEMENTED;
}
// Returns the image buffer size
NS_IMETHODIMP nsJPEGEncoder::GetImageBufferSize(PRUint32 *aOutputSize)
// Returns the number of bytes in the image buffer used.
NS_IMETHODIMP nsJPEGEncoder::GetImageBufferUsed(PRUint32 *aOutputSize)
{
NS_ENSURE_ARG_POINTER(aOutputSize);
*aOutputSize = mImageBufferSize;
*aOutputSize = mImageBufferUsed;
return NS_OK;
}

View File

@ -206,11 +206,11 @@ NS_IMETHODIMP nsPNGEncoder::StartImageEncode(PRUint32 aWidth,
return NS_OK;
}
// Returns the image buffer size
NS_IMETHODIMP nsPNGEncoder::GetImageBufferSize(PRUint32 *aOutputSize)
// Returns the number of bytes in the image buffer used.
NS_IMETHODIMP nsPNGEncoder::GetImageBufferUsed(PRUint32 *aOutputSize)
{
NS_ENSURE_ARG_POINTER(aOutputSize);
*aOutputSize = mImageBufferSize;
*aOutputSize = mImageBufferUsed;
return NS_OK;
}

View File

@ -44,7 +44,7 @@
/**
* imgIEncoder interface
*/
[scriptable, uuid(d02e2d95-072d-4b91-8b8f-1300e45fcb2b)]
[scriptable, uuid(4baa2d6e-fee7-42df-ae3f-5fbebc0c267c)]
interface imgIEncoder : nsIAsyncInputStream
{
// Possible values for outputOptions. Multiple values are semicolon-separated.
@ -159,8 +159,9 @@ interface imgIEncoder : nsIAsyncInputStream
/*
* Sometimes an encoder can contain another encoder and direct access
* to its buffer is necessary.
* to its buffer is necessary. It is only safe to assume that the buffer
* returned from getImageBuffer() is of size equal to getImageBufferUsed().
*/
[noscript] unsigned long getImageBufferSize();
[noscript] unsigned long getImageBufferUsed();
[noscript] charPtr getImageBuffer();
};