summaryrefslogtreecommitdiffstats
path: root/image/decoders
diff options
context:
space:
mode:
Diffstat (limited to 'image/decoders')
-rw-r--r--image/decoders/nsGIFDecoder2.cpp3
-rw-r--r--image/decoders/nsPNGDecoder.cpp19
-rw-r--r--image/decoders/nsPNGDecoder.h1
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();