From dbdf6d210b7e34d66df8b08596c690b9b12e7f8a Mon Sep 17 00:00:00 2001 From: Matt Sarett Date: Tue, 8 Nov 2016 15:26:56 -0500 Subject: Fail jpeg decodes on too many progressive scans BUG:642462 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4560 Change-Id: I22891ce1e0b3a1bedefc34dadd5cf34dfc301b79 Reviewed-on: https://skia-review.googlesource.com/4560 Reviewed-by: Leon Scroggins Commit-Queue: Matt Sarett --- resources/invalid_images/many-progressive-scans.jpg | Bin 0 -> 4477 bytes src/codec/SkJpegDecoderMgr.cpp | 13 +++++++++++++ src/codec/SkJpegDecoderMgr.h | 1 + tests/CodecTest.cpp | 1 + 4 files changed, 15 insertions(+) create mode 100644 resources/invalid_images/many-progressive-scans.jpg diff --git a/resources/invalid_images/many-progressive-scans.jpg b/resources/invalid_images/many-progressive-scans.jpg new file mode 100644 index 0000000000..05a1a00b09 Binary files /dev/null and b/resources/invalid_images/many-progressive-scans.jpg differ diff --git a/src/codec/SkJpegDecoderMgr.cpp b/src/codec/SkJpegDecoderMgr.cpp index 70401c0391..c2837aa2b4 100644 --- a/src/codec/SkJpegDecoderMgr.cpp +++ b/src/codec/SkJpegDecoderMgr.cpp @@ -25,6 +25,17 @@ static void output_message(j_common_ptr info) { print_message(info, "output_message"); } +static void progress_monitor(j_common_ptr info) { + int scan = ((j_decompress_ptr)info)->input_scan_number; + // Progressive images with a very large number of scans can cause the + // decoder to hang. Here we use the progress monitor to abort on + // a very large number of scans. 100 is arbitrary, but much larger + // than the number of scans we might expect in a normal image. + if (scan >= 100) { + skjpeg_err_exit(info); + } +} + bool JpegDecoderMgr::returnFalse(const char caller[]) { print_message((j_common_ptr) &fDInfo, caller); return false; @@ -71,6 +82,8 @@ void JpegDecoderMgr::init() { fInit = true; fDInfo.src = &fSrcMgr; fDInfo.err->output_message = &output_message; + fDInfo.progress = &fProgressMgr; + fProgressMgr.progress_monitor = &progress_monitor; } JpegDecoderMgr::~JpegDecoderMgr() { diff --git a/src/codec/SkJpegDecoderMgr.h b/src/codec/SkJpegDecoderMgr.h index 7bc422d4ff..272c5b4b1c 100644 --- a/src/codec/SkJpegDecoderMgr.h +++ b/src/codec/SkJpegDecoderMgr.h @@ -68,6 +68,7 @@ private: jpeg_decompress_struct fDInfo; skjpeg_source_mgr fSrcMgr; skjpeg_error_mgr fErrorMgr; + jpeg_progress_mgr fProgressMgr; bool fInit; }; diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp index 32ad959693..dacabca3fd 100644 --- a/tests/CodecTest.cpp +++ b/tests/CodecTest.cpp @@ -1439,4 +1439,5 @@ DEF_TEST(Codec_InvalidImages, r) { // ASAN will complain if there is an issue. test_invalid_images(r, "invalid_images/int_overflow.ico", false); test_invalid_images(r, "invalid_images/skbug5887.gif", true); + test_invalid_images(r, "invalid_images/many-progressive-scans.jpg", false); } -- cgit v1.2.3