diff options
author | halcanary <halcanary@google.com> | 2014-08-01 10:31:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-01 10:31:48 -0700 |
commit | a0cc8334dab67746c6a74807db92ce2607ed52ff (patch) | |
tree | 9c05d8ac8bd731ea77abb75817c077585af72306 | |
parent | 66058b614d9c8cb63c24b1c779dd1a9a80752217 (diff) |
add a libjpeg test
This tests for a bug in libjpeg where INT32 is typedefed to long
and memory is written to outside of the array.
BUG=skia:2791
R=djsollen@google.com, mtklein@google.com
Author: halcanary@google.com
Review URL: https://codereview.chromium.org/435753002
-rw-r--r-- | tests/ImageDecodingTest.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/tests/ImageDecodingTest.cpp b/tests/ImageDecodingTest.cpp index 89f59c5cdb..5e63611348 100644 --- a/tests/ImageDecodingTest.cpp +++ b/tests/ImageDecodingTest.cpp @@ -752,3 +752,67 @@ DEF_TEST(DiscardablePixelRef_SecondLockColorTableCheck, r) { REPORTER_ASSERT(r, bitmap.getColorTable() && "second pass"); } } + + +//////////////////////////////////////////////////////////////////////////////// +namespace { +class SingleAllocator : public SkBitmap::Allocator { +public: + SingleAllocator(void* p, size_t s) : fPixels(p), fSize(s) { } + ~SingleAllocator() {} + // If the pixels in fPixels are big enough, use them. + virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE { + SkASSERT(bm); + if (bm->info().getSafeSize(bm->rowBytes()) <= fSize) { + bm->setPixels(fPixels, ct); + fPixels = NULL; + fSize = 0; + return true; + } + return bm->allocPixels(NULL, ct); + } + bool ready() { return fPixels != NULL; } +private: + void* fPixels; + size_t fSize; +}; +} // namespace + +/* This tests for a bug in libjpeg where INT32 is typedefed to long + and memory can be written to outside of the array. */ +DEF_TEST(ImageDecoding_JpegOverwrite, r) { + SkString resourceDir = GetResourcePath(); + SkString path = SkOSPath::Join(resourceDir.c_str(), "randPixels.jpg"); + SkAutoTUnref<SkStreamAsset> stream( + SkStream::NewFromFile(path.c_str())); + if (!stream.get()) { + SkDebugf("\nPath '%s' missing.\n", path.c_str()); + return; + } + SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); + if (NULL == decoder.get()) { + ERRORF(r, "\nSkImageDecoder::Factory failed.\n"); + return; + } + SkAssertResult(stream->rewind()); + + static const uint16_t sentinal = 0xBEEF; + static const int pixelCount = 16; + SkAutoTMalloc<uint16_t> pixels(pixelCount + 1); + // pixels.get() should be 4-byte aligned. + // This is necessary to reproduce the bug. + + pixels[pixelCount] = sentinal; // This value should not be changed. + + SkAutoTUnref<SingleAllocator> allocator( + SkNEW_ARGS(SingleAllocator, + ((void*)pixels.get(), sizeof(uint16_t) * pixelCount))); + decoder->setAllocator(allocator); + decoder->setSampleSize(2); + SkBitmap bitmap; + bool success = decoder->decode(stream, &bitmap, kRGB_565_SkColorType, + SkImageDecoder::kDecodePixels_Mode); + REPORTER_ASSERT(r, success); + REPORTER_ASSERT(r, !allocator->ready()); // Decoder used correct memory + REPORTER_ASSERT(r, sentinal == pixels[pixelCount]); +} |