Fix decoding incomplete PNG images
If process_data is unable to read (and therefore process) as many bytes as it expects, process the bytes read before returning false. Fixes differences in Gold. Add a test that verifies that it is okay to call png_process_data with 0 bytes. (We could special case 0, but libpng already checks for 0.) Change-Id: Id500b9305ee3bb6a1a7e8fc70d4e723cb4742b55 Reviewed-on: https://skia-review.googlesource.com/14144 Commit-Queue: Leon Scroggins <scroggo@google.com> Reviewed-by: Matt Sarett <msarett@google.com>
This commit is contained in:
parent
df2bf21364
commit
b644650e09
@ -132,10 +132,11 @@ static inline bool process_data(png_structp png_ptr, png_infop info_ptr,
|
||||
SkStream* stream, void* buffer, size_t bufferSize, size_t length) {
|
||||
while (length > 0) {
|
||||
const size_t bytesToProcess = std::min(bufferSize, length);
|
||||
if (stream->read(buffer, bytesToProcess) < bytesToProcess) {
|
||||
const size_t bytesRead = stream->read(buffer, bytesToProcess);
|
||||
png_process_data(png_ptr, info_ptr, (png_bytep) buffer, bytesRead);
|
||||
if (bytesRead < bytesToProcess) {
|
||||
return false;
|
||||
}
|
||||
png_process_data(png_ptr, info_ptr, (png_bytep) buffer, bytesToProcess);
|
||||
length -= bytesToProcess;
|
||||
}
|
||||
return true;
|
||||
|
@ -401,3 +401,28 @@ DEF_TEST(Codec_GifPreMap, r) {
|
||||
compare_bitmaps(r, truth, bm);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_TEST(Codec_emptyIDAT, r) {
|
||||
const char* name = "baby_tux.png";
|
||||
sk_sp<SkData> file = GetResourceAsData(name);
|
||||
if (!file) {
|
||||
SkDebugf("REMOVE\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Truncate to the beginning of the IDAT, immediately after the IDAT tag.
|
||||
file = SkData::MakeSubset(file.get(), 0, 80);
|
||||
|
||||
std::unique_ptr<SkCodec> codec(SkCodec::NewFromData(std::move(file)));
|
||||
if (!codec) {
|
||||
ERRORF(r, "Failed to create a codec for %s", name);
|
||||
return;
|
||||
}
|
||||
|
||||
SkBitmap bm;
|
||||
const auto info = standardize_info(codec.get());
|
||||
bm.allocPixels(info);
|
||||
|
||||
const auto result = codec->getPixels(info, bm.getPixels(), bm.rowBytes());
|
||||
REPORTER_ASSERT(r, SkCodec::kIncompleteInput == result);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user