aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2016-11-08 15:26:56 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-08 21:39:15 +0000
commitdbdf6d210b7e34d66df8b08596c690b9b12e7f8a (patch)
tree332212922222c484e9137f628b793b8426b6447a
parent2c3db3263bdc4b91cd7d21dbfe0501fe9bd476a5 (diff)
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 <scroggo@google.com> Commit-Queue: Matt Sarett <msarett@google.com>
-rw-r--r--resources/invalid_images/many-progressive-scans.jpgbin0 -> 4477 bytes
-rw-r--r--src/codec/SkJpegDecoderMgr.cpp13
-rw-r--r--src/codec/SkJpegDecoderMgr.h1
-rw-r--r--tests/CodecTest.cpp1
4 files changed, 15 insertions, 0 deletions
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
--- /dev/null
+++ b/resources/invalid_images/many-progressive-scans.jpg
Binary files 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);
}