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