diff options
Diffstat (limited to 'image/decoders')
-rw-r--r-- | image/decoders/nsGIFDecoder2.cpp | 3 | ||||
-rw-r--r-- | image/decoders/nsPNGDecoder.cpp | 19 | ||||
-rw-r--r-- | image/decoders/nsPNGDecoder.h | 1 |
3 files changed, 21 insertions, 2 deletions
diff --git a/image/decoders/nsGIFDecoder2.cpp b/image/decoders/nsGIFDecoder2.cpp index 9b2de9124a..6dbe12c0af 100644 --- a/image/decoders/nsGIFDecoder2.cpp +++ b/image/decoders/nsGIFDecoder2.cpp @@ -1032,6 +1032,9 @@ LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadLZWData( break; case WriteState::FAILURE: + if (mGIFStruct.images_decoded > 0) { + return Transition::TerminateSuccess(); + } return Transition::TerminateFailure(); } } diff --git a/image/decoders/nsPNGDecoder.cpp b/image/decoders/nsPNGDecoder.cpp index afc2762515..324c7613ca 100644 --- a/image/decoders/nsPNGDecoder.cpp +++ b/image/decoders/nsPNGDecoder.cpp @@ -114,6 +114,7 @@ nsPNGDecoder::nsPNGDecoder(RasterImage* aImage) mDisablePremultipliedAlpha(false), mGotInfoCallback(false), mUsePipeTransform(false), + mErrorIsRecoverable(false), mNumFrames(0) {} nsPNGDecoder::~nsPNGDecoder() { @@ -382,7 +383,9 @@ LexerTransition<nsPNGDecoder::State> nsPNGDecoder::ReadPNGData( // libpng uses setjmp/longjmp for error handling. if (setjmp(png_jmpbuf(mPNG))) { - return Transition::TerminateFailure(); + return (GetFrameCount() > 0 && mErrorIsRecoverable) + ? Transition::TerminateSuccess() + : Transition::TerminateFailure(); } // Pass the data off to libpng. @@ -991,6 +994,16 @@ void nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr) { void nsPNGDecoder::error_callback(png_structp png_ptr, png_const_charp error_msg) { MOZ_LOG(sPNGLog, LogLevel::Error, ("libpng error: %s\n", error_msg)); + + nsPNGDecoder* decoder = + static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr)); + + if (strstr(error_msg, "invalid chunk type")) { + decoder->mErrorIsRecoverable = true; + } else { + decoder->mErrorIsRecoverable = false; + } + png_longjmp(png_ptr, 1); } @@ -1012,7 +1025,9 @@ bool nsPNGDecoder::IsValidICOResource() const { // we need to save the jump buffer here. Otherwise we'll end up without a // proper callstack. if (setjmp(png_jmpbuf(mPNG))) { - // We got here from a longjmp call indirectly from png_get_IHDR + // We got here from a longjmp call indirectly from png_get_IHDR via + // error_callback. Ignore mErrorIsRecoverable: if we got an invalid chunk + // error before even reading the IHDR we can't recover from that. return false; } diff --git a/image/decoders/nsPNGDecoder.h b/image/decoders/nsPNGDecoder.h index 89d66fa5eb..4627302b87 100644 --- a/image/decoders/nsPNGDecoder.h +++ b/image/decoders/nsPNGDecoder.h @@ -103,6 +103,7 @@ class nsPNGDecoder : public Decoder { bool mDisablePremultipliedAlpha; bool mGotInfoCallback; bool mUsePipeTransform; + bool mErrorIsRecoverable; struct AnimFrameInfo { AnimFrameInfo(); |