From 987a61fc5c4fdc46e43d81b7ab149b6bc49ccf46 Mon Sep 17 00:00:00 2001 From: Brad Werth Date: Wed, 9 Nov 2022 17:01:35 +0000 Subject: [PATCH] Bug 1798532 Part 3: Allow JPEGDecoder to handle frame data in the footer. r=tnikkel This also modifies red-bad-marker.jpg to add a SOF6 marker (0xFFC6) in the footer. Differential Revision: https://phabricator.services.mozilla.com/D161637 --- image/decoders/nsJPEGDecoder.cpp | 26 +++++++++++++++++++++++++- image/test/reftest/jpeg/red-bad-marker.jpg | Bin 640 -> 640 bytes 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/image/decoders/nsJPEGDecoder.cpp b/image/decoders/nsJPEGDecoder.cpp index af11ee848b3e..61fb1126b68a 100644 --- a/image/decoders/nsJPEGDecoder.cpp +++ b/image/decoders/nsJPEGDecoder.cpp @@ -199,7 +199,12 @@ LexerTransition nsJPEGDecoder::ReadJPEGData( // Return here if there is a error within libjpeg. nsresult error_code; // This cast to nsresult makes sense because setjmp() returns whatever we - // passed to longjmp(), which was actually an nsresult. + // passed to longjmp(), which was actually an nsresult. These error codes + // have been translated from libjpeg error codes, like so: + // JERR_OUT_OF_MEMORY => NS_ERROR_OUT_OF_MEMORY + // JERR_UNKNOWN_MARKER => NS_ERROR_ILLEGAL_VALUE + // JERR_SOF_UNSUPPORTED => NS_ERROR_INVALID_CONTENT_ENCODING + // => NS_ERROR_FAILURE if ((error_code = static_cast(setjmp(mErr.setjmp_buffer))) != NS_OK) { bool fatal = true; @@ -213,6 +218,22 @@ LexerTransition nsJPEGDecoder::ReadJPEGData( // This is a recoverable error. Consume the marker and continue. mInfo.unread_marker = 0; fatal = false; + } else if (error_code == NS_ERROR_INVALID_CONTENT_ENCODING) { + // The content is encoding frames with a format that libjpeg can't handle. + MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, + ("} (setjmp returned NS_ERROR_INVALID_CONTENT_ENCODING)")); + // Check to see if we're in the done state, which indicates that we've + // already processed the main JPEG data. + bool inDoneState = (mState == JPEG_DONE); + // Whether we succeed or fail, we shouldn't send any more data. + mState = JPEG_SINK_NON_JPEG_TRAILER; + + // If we're in the done state, we exit successfully and attempt to + // display the content we've already received. Otherwise, we fallthrough + // and treat this as a fatal error. + if (inDoneState) { + return Transition::TerminateSuccess(); + } } else { // Error for another reason. (Possibly OOM.) mState = JPEG_ERROR; @@ -689,6 +710,9 @@ my_error_exit(j_common_ptr cinfo) { case JERR_UNKNOWN_MARKER: error_code = NS_ERROR_ILLEGAL_VALUE; break; + case JERR_SOF_UNSUPPORTED: + error_code = NS_ERROR_INVALID_CONTENT_ENCODING; + break; default: error_code = NS_ERROR_FAILURE; } diff --git a/image/test/reftest/jpeg/red-bad-marker.jpg b/image/test/reftest/jpeg/red-bad-marker.jpg index 2dbd6d1fc50af8c7b98f8e80649fe157852c8d67..4abda17e597e95805065d2388d2de72bb927314e 100644 GIT binary patch delta 11 ScwTE@ZD8F{%fx)_|4jfFVg%a& delta 11 ScwTE@ZD8F{%fx*1|26;@cm&G; -- 2.11.4.GIT