SkGifCodec: intersect frameRect with image size
When clearing due to SkCodecAnimation::RestoreBGColor_DisposalMethod,
intersect the frameRect with the image size to prevent clearing outside
the bounds of the allocated memory.
Add a test image, created by the fuzzer.
BUG=skia:6046
Change-Id: I43676d28f82abf093ef801752f3a9e881580924c
Reviewed-on: https://skia-review.googlesource.com/5860
Commit-Queue: Leon Scroggins <scroggo@google.com>
Reviewed-by: Matt Sarett <msarett@google.com>
diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp
index 9a5948b..618a5b5 100644
--- a/src/codec/SkGifCodec.cpp
+++ b/src/codec/SkGifCodec.cpp
@@ -419,18 +419,20 @@
}
const auto* prevFrame = fReader->frameContext(frameContext->getRequiredFrame());
if (prevFrame->getDisposalMethod() == SkCodecAnimation::RestoreBGColor_DisposalMethod) {
- const SkIRect prevRect = prevFrame->frameRect();
- auto left = get_scaled_dimension(prevRect.fLeft, fSwizzler->sampleX());
- auto top = get_scaled_dimension(prevRect.fTop, fSwizzler->sampleY());
- void* const eraseDst = SkTAddOffset<void>(fDst, top * fDstRowBytes
- + left * SkColorTypeBytesPerPixel(dstInfo.colorType()));
- auto width = get_scaled_dimension(prevRect.width(), fSwizzler->sampleX());
- auto height = get_scaled_dimension(prevRect.height(), fSwizzler->sampleY());
- // fSwizzler->fill() would fill to the scaled width of the frame, but we want to
- // fill to the scaled with of the width of the PRIOR frame, so we do all the scaling
- // ourselves and call the static version.
- SkSampler::Fill(dstInfo.makeWH(width, height), eraseDst,
- fDstRowBytes, this->getFillValue(dstInfo), kNo_ZeroInitialized);
+ SkIRect prevRect = prevFrame->frameRect();
+ if (prevRect.intersect(this->getInfo().bounds())) {
+ auto left = get_scaled_dimension(prevRect.fLeft, fSwizzler->sampleX());
+ auto top = get_scaled_dimension(prevRect.fTop, fSwizzler->sampleY());
+ void* const eraseDst = SkTAddOffset<void>(fDst, top * fDstRowBytes
+ + left * SkColorTypeBytesPerPixel(dstInfo.colorType()));
+ auto width = get_scaled_dimension(prevRect.width(), fSwizzler->sampleX());
+ auto height = get_scaled_dimension(prevRect.height(), fSwizzler->sampleY());
+ // fSwizzler->fill() would fill to the scaled width of the frame, but we want to
+ // fill to the scaled with of the width of the PRIOR frame, so we do all the
+ // scaling ourselves and call the static version.
+ SkSampler::Fill(dstInfo.makeWH(width, height), eraseDst,
+ fDstRowBytes, this->getFillValue(dstInfo), kNo_ZeroInitialized);
+ }
}
filledBackground = true;
}