зеркало из https://github.com/mozilla/pjs.git
Bug 514033 - Error recovery for imagelib - part 2 - Notify the superclass error reporting framework when an error occurs.r=joe
This commit is contained in:
Родитель
d90e859bc8
Коммит
7b91b495f6
|
@ -71,7 +71,6 @@ nsBMPDecoder::nsBMPDecoder()
|
|||
mState = eRLEStateInitial;
|
||||
mStateData = 0;
|
||||
mLOH = WIN_HEADER_LENGTH;
|
||||
mError = PR_FALSE;
|
||||
}
|
||||
|
||||
nsBMPDecoder::~nsBMPDecoder()
|
||||
|
@ -100,7 +99,7 @@ nsBMPDecoder::FinishInternal()
|
|||
NS_ABORT_IF_FALSE(GetFrameCount() <= 1, "Multiple BMP frames?");
|
||||
|
||||
// Send notifications if appropriate
|
||||
if (!IsSizeDecode() && !mError && (GetFrameCount() == 1)) {
|
||||
if (!IsSizeDecode() && !IsError() && (GetFrameCount() == 1)) {
|
||||
PostFrameStop();
|
||||
mImage->DecodingComplete();
|
||||
if (mObserver) {
|
||||
|
@ -155,7 +154,7 @@ nsresult
|
|||
nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
||||
{
|
||||
// No forgiveness
|
||||
if (mError)
|
||||
if (IsError())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// aCount=0 means EOF, mCurLine=0 means we're past end of image
|
||||
|
@ -175,7 +174,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
if (mPos == BFH_LENGTH) {
|
||||
ProcessFileHeader();
|
||||
if (mBFH.signature[0] != 'B' || mBFH.signature[1] != 'M') {
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (mBFH.bihsize == OS2_BIH_LENGTH)
|
||||
|
@ -197,7 +196,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
// Verify we support this bit depth
|
||||
if (mBIH.bpp != 1 && mBIH.bpp != 4 && mBIH.bpp != 8 &&
|
||||
mBIH.bpp != 16 && mBIH.bpp != 24 && mBIH.bpp != 32) {
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
|
@ -205,7 +204,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
// Reject extremely wide images to keep the math sane
|
||||
const PRInt32 k64KWidth = 0x0000FFFF;
|
||||
if (mBIH.width < 0 || mBIH.width > k64KWidth) {
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -230,7 +229,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
// Always allocate 256 even though mNumColors might be smaller
|
||||
mColors = new colorTable[256];
|
||||
if (!mColors) {
|
||||
mError = PR_TRUE;
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -255,7 +254,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
// to make exact calculations here, that's unnecessary.
|
||||
// Also, it compensates rounding error.
|
||||
if (!mRow) {
|
||||
mError = PR_TRUE;
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
rv = mImage->AppendFrame(0, 0, mBIH.width, real_height, gfxASurface::ImageFormatRGB24,
|
||||
|
@ -263,7 +262,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mImageData) {
|
||||
mError = PR_TRUE;
|
||||
PostDecoderError(NS_ERROR_FAILURE);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -272,7 +271,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
if (((mBIH.compression == BI_RLE8) && (mBIH.bpp != 8))
|
||||
|| ((mBIH.compression == BI_RLE4) && (mBIH.bpp != 4) && (mBIH.bpp != 1))) {
|
||||
PR_LOG(gBMPLog, PR_LOG_DEBUG, ("BMP RLE8/RLE4 compression only supports 8/4 bits per pixel\n"));
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// Clear the image, as the RLE may jump over areas
|
||||
|
@ -416,7 +415,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
if (((mBIH.compression == BI_RLE8) && (mBIH.bpp != 8))
|
||||
|| ((mBIH.compression == BI_RLE4) && (mBIH.bpp != 4) && (mBIH.bpp != 1))) {
|
||||
PR_LOG(gBMPLog, PR_LOG_DEBUG, ("BMP RLE8/RLE4 compression only supports 8/4 bits per pixel\n"));
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -484,7 +483,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
// pixel too many, but only if their width is odd.
|
||||
mStateData -= mBIH.width & 1;
|
||||
if (mCurPos + mStateData > (PRUint32)mBIH.width) {
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -569,8 +568,8 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
continue;
|
||||
|
||||
default :
|
||||
NS_NOTREACHED("BMP RLE decompression: unknown state!");
|
||||
mError = PR_TRUE;
|
||||
NS_ABORT_IF_FALSE(0, "BMP RLE decompression: unknown state!");
|
||||
PostDecoderError(NS_ERROR_UNEXPECTED);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// Because of the use of the continue statement
|
||||
|
|
|
@ -178,7 +178,6 @@ private:
|
|||
|
||||
ERLEState mState; ///< Maintains the current state of the RLE decoding
|
||||
PRUint32 mStateData;///< Decoding information that is needed depending on mState
|
||||
PRBool mError; ///< Did we hit an error?
|
||||
|
||||
/** Set mBFH from the raw data in mRawBuf, converting from little-endian
|
||||
* data to native data as necessary */
|
||||
|
|
|
@ -117,7 +117,6 @@ nsGIFDecoder2::nsGIFDecoder2()
|
|||
, mLastFlushedPass(0)
|
||||
, mGIFOpen(PR_FALSE)
|
||||
, mSawTransparency(PR_FALSE)
|
||||
, mError(PR_FALSE)
|
||||
, mEnded(PR_FALSE)
|
||||
{
|
||||
// Clear out the structure, excluding the arrays
|
||||
|
@ -147,7 +146,7 @@ nsresult
|
|||
nsGIFDecoder2::FinishInternal()
|
||||
{
|
||||
// Send notifications if appropriate
|
||||
if (!IsSizeDecode() && !mError) {
|
||||
if (!IsSizeDecode() && !IsError()) {
|
||||
if (mCurrentFrame == mGIFStruct.images_decoded)
|
||||
EndImageFrame();
|
||||
EndGIF(/* aSuccess = */ PR_TRUE);
|
||||
|
@ -194,7 +193,7 @@ nsresult
|
|||
nsGIFDecoder2::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
||||
{
|
||||
// Don't forgive previously flagged errors
|
||||
if (mError)
|
||||
if (IsError())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Push the data to the GIF decoder
|
||||
|
@ -212,7 +211,7 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
// of an animated gif, we still want to display it (mostly for legacy reasons).
|
||||
// libpr0n code is strict, so we have to lie and tell it we were successful. So
|
||||
// if we have something to salvage, we send off final decode notifications, and
|
||||
// pretend that we're decoded. Otherwise, we set mError.
|
||||
// pretend that we're decoded. Otherwise, we set a data error.
|
||||
if (NS_FAILED(rv)) {
|
||||
|
||||
// Determine if we want to salvage the situation.
|
||||
|
@ -223,12 +222,12 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
EndGIF(/* aSuccess = */ PR_TRUE);
|
||||
}
|
||||
|
||||
// Otherwise, set mError
|
||||
// Otherwise, set an error
|
||||
else
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
}
|
||||
|
||||
return mError ? NS_ERROR_FAILURE : NS_OK;
|
||||
return IsError() ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
|
|
@ -99,7 +99,6 @@ private:
|
|||
PRUint8 mColorMask; // Apply this to the pixel to keep within colormap
|
||||
PRPackedBool mGIFOpen;
|
||||
PRPackedBool mSawTransparency;
|
||||
PRPackedBool mError;
|
||||
PRPackedBool mEnded;
|
||||
|
||||
gif_struct mGIFStruct;
|
||||
|
|
|
@ -79,7 +79,6 @@ nsICODecoder::nsICODecoder()
|
|||
mColors = nsnull;
|
||||
mRow = nsnull;
|
||||
mHaveAlphaData = mDecodingAndMask = PR_FALSE;
|
||||
mError = PR_FALSE;
|
||||
}
|
||||
|
||||
nsICODecoder::~nsICODecoder()
|
||||
|
@ -120,7 +119,7 @@ nsICODecoder::FinishInternal()
|
|||
NS_ABORT_IF_FALSE(GetFrameCount() <= 1, "Multiple ICO frames?");
|
||||
|
||||
// Send notifications if appropriate
|
||||
if (!IsSizeDecode() && !mError && (GetFrameCount() == 1)) {
|
||||
if (!IsSizeDecode() && !IsError() && (GetFrameCount() == 1)) {
|
||||
|
||||
// Invalidate
|
||||
nsIntRect r(0, 0, mDirEntry.mWidth, mDirEntry.mHeight);
|
||||
|
@ -141,7 +140,7 @@ nsresult
|
|||
nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
||||
{
|
||||
// No forgiveness
|
||||
if (mError)
|
||||
if (IsError())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!aCount) // aCount=0 means EOF
|
||||
|
@ -150,7 +149,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
while (aCount && (mPos < ICONCOUNTOFFSET)) { // Skip to the # of icons.
|
||||
if (mPos == 2) { // if the third byte is 1: This is an icon, 2: a cursor
|
||||
if ((*aBuffer != 1) && (*aBuffer != 2)) {
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mIsCursor = (*aBuffer == 2);
|
||||
|
@ -194,7 +193,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
// ensure mImageOffset is >= the size of the direntry headers (bug #245631)
|
||||
PRUint32 minImageOffset = DIRENTRYOFFSET + mNumIcons*sizeof(mDirEntryArray);
|
||||
if (mImageOffset < minImageOffset) {
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -248,13 +247,13 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
mNumColors = 256;
|
||||
break;
|
||||
default:
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mColors = new colorTable[mNumColors];
|
||||
if (!mColors) {
|
||||
mError = PR_TRUE;
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +277,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
// to make exact calculations here, that's unnecessary.
|
||||
// Also, it compensates rounding error.
|
||||
if (!mRow) {
|
||||
mError = PR_TRUE;
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -325,10 +324,12 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
|
||||
// Ensure memory has been allocated before decoding. If we get this far
|
||||
// without allocated memory, the file is most likely invalid.
|
||||
// XXXbholley - If null values can be triggered by bad input, why are we
|
||||
// asserting here?
|
||||
NS_ASSERTION(mRow, "mRow is null");
|
||||
NS_ASSERTION(mImageData, "mImageData is null");
|
||||
if (!mRow || !mImageData) {
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -414,7 +415,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
break;
|
||||
default:
|
||||
// This is probably the wrong place to check this...
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -436,7 +437,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
mCurLine = mDirEntry.mHeight;
|
||||
mRow = (PRUint8*)realloc(mRow, rowSize);
|
||||
if (!mRow) {
|
||||
mError = PR_TRUE;
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -445,7 +446,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
NS_ASSERTION(mRow, "mRow is null");
|
||||
NS_ASSERTION(mImageData, "mImageData is null");
|
||||
if (!mRow || !mImageData) {
|
||||
mError = PR_TRUE;
|
||||
PostDataError();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,6 @@ private:
|
|||
PRPackedBool mHaveAlphaData;
|
||||
PRPackedBool mIsCursor;
|
||||
PRPackedBool mDecodingAndMask;
|
||||
PRPackedBool mError;
|
||||
};
|
||||
|
||||
} // namespace imagelib
|
||||
|
|
|
@ -92,6 +92,9 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
if (IsError())
|
||||
return NS_IMAGELIB_ERROR_FAILURE;
|
||||
|
||||
// We put this here to avoid errors about crossing initialization with case
|
||||
// jumps on linux.
|
||||
PRUint32 bytesToRead = 0;
|
||||
|
@ -133,7 +136,7 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
gfxASurface::ImageFormatARGB32,
|
||||
&mImageData, &mPixBytesTotal);
|
||||
if (NS_FAILED(rv)) {
|
||||
mState = iconStateError;
|
||||
PostDecoderError(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -175,10 +178,6 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
aCount = 0;
|
||||
|
||||
break;
|
||||
|
||||
case iconStateError:
|
||||
return NS_IMAGELIB_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,8 +96,7 @@ enum {
|
|||
iconStateStart = 0,
|
||||
iconStateHaveHeight = 1,
|
||||
iconStateReadPixels = 2,
|
||||
iconStateFinished = 3,
|
||||
iconStateError = 4
|
||||
iconStateFinished = 3
|
||||
};
|
||||
|
||||
} // namespace imagelib
|
||||
|
|
|
@ -155,6 +155,7 @@ nsJPEGDecoder::InitInternal()
|
|||
/* If we get here, the JPEG code has signaled an error.
|
||||
* We need to clean up the JPEG object, close the input file, and return.
|
||||
*/
|
||||
PostDecoderError(NS_ERROR_FAILURE);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -217,6 +218,7 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
nsresult error_code;
|
||||
if ((error_code = setjmp(mErr.setjmp_buffer)) != 0) {
|
||||
if (error_code == NS_ERROR_FAILURE) {
|
||||
PostDataError();
|
||||
/* Error due to corrupt stream - return NS_OK and consume silently
|
||||
so that libpr0n doesn't throw away a partial image load */
|
||||
mState = JPEG_SINK_NON_JPEG_TRAILER;
|
||||
|
@ -227,6 +229,7 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
/* Error due to reasons external to the stream (probably out of
|
||||
memory) - let libpr0n attempt to clean up, even though
|
||||
mozilla is seconds away from falling flat on its face. */
|
||||
PostDecoderError(error_code);
|
||||
mState = JPEG_ERROR;
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("} (setjmp returned an error)"));
|
||||
|
@ -297,6 +300,7 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
break;
|
||||
default:
|
||||
mState = JPEG_ERROR;
|
||||
PostDataError();
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("} (unknown colorpsace (1))"));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -313,6 +317,7 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
break;
|
||||
default:
|
||||
mState = JPEG_ERROR;
|
||||
PostDataError();
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("} (unknown colorpsace (2))"));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -362,6 +367,7 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
break;
|
||||
default:
|
||||
mState = JPEG_ERROR;
|
||||
PostDataError();
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("} (unknown colorpsace (3))"));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -386,6 +392,7 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
gfxASurface::ImageFormatRGB24,
|
||||
&mImageData, &imagelength))) {
|
||||
mState = JPEG_ERROR;
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("} (could not initialize image frame)"));
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -551,9 +558,7 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
break;
|
||||
|
||||
case JPEG_ERROR:
|
||||
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
|
||||
("[this=%p] nsJPEGDecoder::ProcessData -- entering JPEG_ERROR case\n", this));
|
||||
return NS_ERROR_FAILURE;
|
||||
NS_ABORT_IF_FALSE(0, "Should always return immediately after error and not re-enter decoder");
|
||||
}
|
||||
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
|
|
|
@ -86,7 +86,7 @@ nsPNGDecoder::nsPNGDecoder() :
|
|||
mCMSLine(nsnull), interlacebuf(nsnull),
|
||||
mInProfile(nsnull), mTransform(nsnull),
|
||||
mHeaderBuf(nsnull), mHeaderBytesRead(0),
|
||||
mChannels(0), mError(PR_FALSE), mFrameIsHidden(PR_FALSE),
|
||||
mChannels(0), mFrameIsHidden(PR_FALSE),
|
||||
mNotifiedDone(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
@ -242,8 +242,10 @@ nsPNGDecoder::InitInternal()
|
|||
// For size decodes, we only need a small buffer
|
||||
if (IsSizeDecode()) {
|
||||
mHeaderBuf = (PRUint8 *)nsMemory::Alloc(BYTES_NEEDED_FOR_DIMENSIONS);
|
||||
if (!mHeaderBuf)
|
||||
if (!mHeaderBuf) {
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -255,11 +257,14 @@ nsPNGDecoder::InitInternal()
|
|||
mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, nsPNGDecoder::error_callback,
|
||||
nsPNGDecoder::warning_callback);
|
||||
if (!mPNG)
|
||||
if (!mPNG) {
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mInfo = png_create_info_struct(mPNG);
|
||||
if (!mInfo) {
|
||||
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||
png_destroy_read_struct(&mPNG, NULL, NULL);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -308,7 +313,7 @@ nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
PRUint32 height = 0;
|
||||
|
||||
// No forgiveness if we previously hit an error
|
||||
if (mError)
|
||||
if (IsError())
|
||||
goto error;
|
||||
|
||||
// If we only want width/height, we don't need to go through libpng
|
||||
|
@ -328,16 +333,20 @@ nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
if (mHeaderBytesRead == BYTES_NEEDED_FOR_DIMENSIONS) {
|
||||
|
||||
// Check that the signature bytes are right
|
||||
if (memcmp(mHeaderBuf, pngSignatureBytes, sizeof(pngSignatureBytes)))
|
||||
if (memcmp(mHeaderBuf, pngSignatureBytes, sizeof(pngSignatureBytes))) {
|
||||
PostDataError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Grab the width and height, accounting for endianness (thanks libpng!)
|
||||
width = png_get_uint_32(mHeaderBuf + WIDTH_OFFSET);
|
||||
height = png_get_uint_32(mHeaderBuf + HEIGHT_OFFSET);
|
||||
|
||||
// Too big?
|
||||
if ((width > MOZ_PNG_MAX_DIMENSION) || (height > MOZ_PNG_MAX_DIMENSION))
|
||||
if ((width > MOZ_PNG_MAX_DIMENSION) || (height > MOZ_PNG_MAX_DIMENSION)) {
|
||||
PostDataError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Post our size to the superclass
|
||||
PostSize(width, height);
|
||||
|
@ -349,6 +358,12 @@ nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
|
||||
// libpng uses setjmp/longjmp for error handling - set the buffer
|
||||
if (setjmp(png_jmpbuf(mPNG))) {
|
||||
|
||||
// We might not really know what caused the error, but it makes more
|
||||
// sense to blame the data.
|
||||
if (!IsError())
|
||||
PostDataError();
|
||||
|
||||
png_destroy_read_struct(&mPNG, &mInfo, NULL);
|
||||
goto error;
|
||||
}
|
||||
|
@ -362,7 +377,7 @@ nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
|
|||
|
||||
// Consolidate error handling
|
||||
error:
|
||||
mError = PR_TRUE;
|
||||
NS_ABORT_IF_FALSE(IsError(), "Should only get here if we flagged an error!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -791,9 +806,7 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
}
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unknown PNG format!");
|
||||
NS_ABORT();
|
||||
break;
|
||||
longjmp(png_jmpbuf(decoder->mPNG), 1);
|
||||
}
|
||||
|
||||
if (!rowHasNoAlpha)
|
||||
|
@ -854,7 +867,7 @@ nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr)
|
|||
static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
|
||||
|
||||
// We shouldn't get here if we've hit an error
|
||||
NS_ABORT_IF_FALSE(!decoder->mError, "Finishing up PNG but hit error!");
|
||||
NS_ABORT_IF_FALSE(!decoder->IsError(), "Finishing up PNG but hit error!");
|
||||
|
||||
#ifdef PNG_APNG_SUPPORTED
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) {
|
||||
|
|
|
@ -91,7 +91,6 @@ public:
|
|||
PRUint32 mHeaderBytesRead;
|
||||
|
||||
PRUint8 mChannels;
|
||||
PRPackedBool mError;
|
||||
PRPackedBool mFrameHasNoAlpha;
|
||||
PRPackedBool mFrameIsHidden;
|
||||
PRPackedBool mNotifiedDone;
|
||||
|
|
Загрузка…
Ссылка в новой задаче