summaryrefslogtreecommitdiffstats
path: root/image/decoders/nsPNGDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'image/decoders/nsPNGDecoder.cpp')
-rw-r--r--image/decoders/nsPNGDecoder.cpp19
1 files changed, 17 insertions, 2 deletions
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;
}