Bug 639303. r=joe

This commit is contained in:
Mats Palmgren 2011-05-11 11:46:59 +02:00
parent 17cdd6713d
commit dda59f8318
7 changed files with 53 additions and 9 deletions

View File

@ -196,6 +196,11 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
// Post our size to the superclass
PostSize(mBIH.width, real_height);
if (HasError()) {
// Setting the size lead to an error; this can happen when for example
// a multipart channel sends an image of a different size.
return;
}
// We have the size. If we're doing a size decode, we got what
// we came for.

View File

@ -916,6 +916,12 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, PRUint32 aCount)
}
// Create the image container with the right size.
BeginGIF();
if (HasError()) {
// Setting the size lead to an error; this can happen when for example
// a multipart channel sends an image of a different size.
mGIFStruct.state = gif_error;
return;
}
// If we were doing a size decode, we're done
if (IsSizeDecode())

View File

@ -99,6 +99,12 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
// Post our size to the superclass
PostSize(mWidth, mHeight);
if (HasError()) {
// Setting the size lead to an error; this can happen when for example
// a multipart channel sends an image of a different size.
mState = iconStateFinished;
return;
}
// If We're doing a size decode, we're done
if (IsSizeDecode()) {

View File

@ -256,6 +256,12 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
// Post our size to the superclass
PostSize(mInfo.image_width, mInfo.image_height);
if (HasError()) {
// Setting the size lead to an error; this can happen when for example
// a multipart channel sends an image of a different size.
mState = JPEG_ERROR;
return;
}
/* If we're doing a size decode, we're done. */
if (IsSizeDecode())

View File

@ -512,6 +512,11 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
// Post our size to the superclass
decoder->PostSize(width, height);
if (decoder->HasError()) {
// Setting the size lead to an error; this can happen when for example
// a multipart channel sends an image of a different size.
longjmp(png_jmpbuf(decoder->mPNG), 1);
}
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr);

View File

@ -121,6 +121,7 @@ public:
bool HasDataError() { return mDataError; };
bool HasDecoderError() { return NS_FAILED(mFailCode); };
nsresult GetDecoderError() { return mFailCode; };
void PostResizeError() { PostDataError(); }
// flags. Keep these in sync with imgIContainer.idl.
// SetDecodeFlags must be called before Init(), otherwise

View File

@ -924,6 +924,11 @@ RasterImage::SetSize(PRInt32 aWidth, PRInt32 aHeight)
else
NS_WARNING("Multipart channel sent an image of a different size");
// Make the decoder aware of the error so that it doesn't try to call
// FinishInternal during ShutdownDecoder.
if (mDecoder)
mDecoder->PostResizeError();
DoError();
return NS_ERROR_UNEXPECTED;
}
@ -1239,6 +1244,7 @@ RasterImage::AddSourceData(const char *aBuffer, PRUint32 aCount)
// We're not storing source data, so this data is probably coming straight
// from the network. In this case, we want to display data as soon as we
// get it, so we want to flush invalidations after every write.
nsRefPtr<Decoder> kungFuDeathGrip = mDecoder;
mInDecoder = PR_TRUE;
mDecoder->FlushInvalidations();
mInDecoder = PR_FALSE;
@ -2208,14 +2214,16 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
bool wasSizeDecode = mDecoder->IsSizeDecode();
// Finalize the decoder
// null out mDecoder, _then_ check for errors on the close (otherwise the
// error routine might re-invoke ShutdownDecoder)
nsRefPtr<Decoder> decoder = mDecoder;
mDecoder = nsnull;
mInDecoder = PR_TRUE;
mDecoder->Finish();
decoder->Finish();
mInDecoder = PR_FALSE;
// null out the decoder, _then_ check for errors on the close (otherwise the
// error routine might re-invoke ShutdownDecoder)
nsresult decoderStatus = mDecoder->GetDecoderError();
mDecoder = nsnull;
nsresult decoderStatus = decoder->GetDecoderError();
if (NS_FAILED(decoderStatus)) {
DoError();
return decoderStatus;
@ -2260,6 +2268,7 @@ RasterImage::WriteToDecoder(const char *aBuffer, PRUint32 aCount)
}
// Write
nsRefPtr<Decoder> kungFuDeathGrip = mDecoder;
mInDecoder = PR_TRUE;
mDecoder->Write(aBuffer, aCount);
mInDecoder = PR_FALSE;
@ -2271,6 +2280,9 @@ RasterImage::WriteToDecoder(const char *aBuffer, PRUint32 aCount)
curframe->UnlockImageData();
}
if (!mDecoder)
return NS_ERROR_FAILURE;
CONTAINER_ENSURE_SUCCESS(mDecoder->GetDecoderError());
// Keep track of the total number of bytes written over the lifetime of the
@ -2418,18 +2430,19 @@ RasterImage::SyncDecode()
// image as possible. We've send the decoder all of our data, so now's a good
// time to flush any invalidations (in case we don't have all the data and what
// we got left us mid-frame).
nsRefPtr<Decoder> kungFuDeathGrip = mDecoder;
mInDecoder = PR_TRUE;
mDecoder->FlushInvalidations();
mInDecoder = PR_FALSE;
// If we finished the decode, shutdown the decoder
if (IsDecodeFinished()) {
if (mDecoder && IsDecodeFinished()) {
rv = ShutdownDecoder(eShutdownIntent_Done);
CONTAINER_ENSURE_SUCCESS(rv);
}
// All good!
return NS_OK;
// All good if no errors!
return mError ? NS_ERROR_FAILURE : NS_OK;
}
//******************************************************************************
@ -2660,6 +2673,8 @@ imgDecodeWorker::Run()
if (!image->mDecoder)
return NS_OK;
nsRefPtr<Decoder> decoderKungFuDeathGrip = image->mDecoder;
// Size decodes are cheap and we more or less want them to be
// synchronous. Write all the data in that case, otherwise write a
// chunk
@ -2700,7 +2715,7 @@ imgDecodeWorker::Run()
}
// If the decode finished, shutdown the decoder
if (image->IsDecodeFinished()) {
if (image->mDecoder && image->IsDecodeFinished()) {
rv = image->ShutdownDecoder(RasterImage::eShutdownIntent_Done);
if (NS_FAILED(rv)) {
image->DoError();