diff options
author | Matt Sarett <msarett@google.com> | 2016-07-21 09:19:47 -0400 |
---|---|---|
committer | gitbuildkicker <android-build@google.com> | 2016-08-31 22:20:23 -0700 |
commit | 30ae0721bf9caaf31ddde08db680094e98e1230a (patch) | |
tree | ef5c050e75481fd2ce8be549961651094859886b | |
parent | 3906c7fd66aa70385d73a0dba51944bd3db74e93 (diff) | |
download | skia-android-7.0.0_r14.tar.gz |
Fix rewinding bug in SkJpegCodec (cherry picked from Skia)android-7.0.0_r14android-7.0.0_r13android-7.0.0_r12nougat-bugfix-release
Performing a sampled and/or subset decode will create some state
in SkJpegCodec. If we fail to clean up this state properly,
subsequent decodes may try to reuse (and potentailly overflow)
the leftover memory.
Committed: https://skia.googlesource.com/skia/+/2812f03d54b7fa4fd3d724505155d44a5343d91b
BUG:30190637
BUG:30081412
Change-Id: I3fc2220c1cf5b6e2bc68e87e19cf54576e2b7a74
(cherry picked from commit 63a53c1e4b347775d4a36c0826fcd249d0b98f20)
(cherry picked from commit 52d00b3be74144019413d7aac734e012c00c87c5)
-rw-r--r-- | src/codec/SkJpegCodec.cpp | 11 | ||||
-rw-r--r-- | tests/CodexTest.cpp | 29 |
2 files changed, 35 insertions, 5 deletions
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index d36051511c..77ad5ddb72 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -80,6 +80,7 @@ SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, : INHERITED(srcInfo, stream) , fDecoderMgr(decoderMgr) , fReadyState(decoderMgr->dinfo()->global_state) + , fSrcRow(nullptr) , fSwizzlerSubset(SkIRect::MakeEmpty()) {} @@ -155,6 +156,11 @@ bool SkJpegCodec::onRewind() { } SkASSERT(nullptr != decoderMgr); fDecoderMgr.reset(decoderMgr); + + fSwizzler.reset(nullptr); + fSrcRow = nullptr; + fStorage.free(); + return true; } @@ -410,11 +416,6 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, return kInvalidConversion; } - // Remove objects used for sampling. - fSwizzler.reset(nullptr); - fSrcRow = nullptr; - fStorage.free(); - // Now, given valid output dimensions, we can start the decompress if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { SkCodecPrintf("start decompress failed\n"); diff --git a/tests/CodexTest.cpp b/tests/CodexTest.cpp index 51e41235cb..8ce63029a6 100644 --- a/tests/CodexTest.cpp +++ b/tests/CodexTest.cpp @@ -971,3 +971,32 @@ DEF_TEST(Codec_wbmp_max_size, r) { REPORTER_ASSERT(r, !codec); } + +DEF_TEST(Codec_jpeg_rewind, r) { + const char* path = "mandrill_512_q075.jpg"; + SkAutoTDelete<SkStream> stream(resource(path)); + if (!stream) { + SkDebugf("Missing resource '%s'\n", path); + return; + } + SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(stream.release())); + if (!codec) { + ERRORF(r, "Unable to create codec '%s'.", path); + return; + } + + const int width = codec->getInfo().width(); + const int height = codec->getInfo().height(); + size_t rowBytes = sizeof(SkPMColor) * width; + SkAutoMalloc pixelStorage(height * rowBytes); + + // Perform a sampled decode. + SkAndroidCodec::AndroidOptions opts; + opts.fSampleSize = 12; + codec->getAndroidPixels(codec->getInfo().makeWH(width / 12, height / 12), pixelStorage.get(), + rowBytes, &opts); + + // Rewind the codec and perform a full image decode. + SkCodec::Result result = codec->getPixels(codec->getInfo(), pixelStorage.get(), rowBytes); + REPORTER_ASSERT(r, SkCodec::kSuccess == result); +} |