Guard against overflow in blur code.
This fuzz creates a blur that has w = 1 and h = 2^31 - epsilon. And a filter sigma of 360. This causes the intermediate buffer size > 2^31. This causes the multiply in the following code SkMaskBlurFilter.cpp:1023: tmpStart + tmpW * tmpH to overflow. Because tmpW = source height, which is near 2^31, and tmpH is about 3*360. Cause the blur to fail if the intermediate buffer is > INT_MAX. Bug: oss-fuzz:49061 Change-Id: I4f9f6bbe76cd71da1ac86562771ca393852452c4 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/558305 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
2fd7b18043
commit
b70a030066
@ -11,6 +11,8 @@
|
||||
#include "include/private/SkTo.h"
|
||||
#include "src/core/SkSafeMath.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
/** returns the product if it is positive and fits in 31 bits. Otherwise this
|
||||
returns 0.
|
||||
*/
|
||||
@ -57,27 +59,29 @@ SkMask SkMask::PrepareDestination(int radiusX, int radiusY, const SkMask& src) {
|
||||
SkSafeMath safe;
|
||||
|
||||
SkMask dst;
|
||||
dst.fImage = nullptr;
|
||||
dst.fFormat = SkMask::kA8_Format;
|
||||
|
||||
// dstW = srcW + 2 * radiusX;
|
||||
size_t dstW = safe.add(src.fBounds.width(), safe.add(radiusX, radiusX));
|
||||
// dstH = srcH + 2 * radiusY;
|
||||
size_t dstH = safe.add(src.fBounds.height(), safe.add(radiusY, radiusY));
|
||||
|
||||
if (!SkTFitsIn<int>(dstW) || !SkTFitsIn<int>(dstH)) {
|
||||
dst.fBounds.setEmpty();
|
||||
dst.fRowBytes = 0;
|
||||
} else {
|
||||
dst.fBounds.setWH(SkTo<int>(dstW), SkTo<int>(dstH));
|
||||
dst.fBounds.offset(src.fBounds.x(), src.fBounds.y());
|
||||
dst.fBounds.offset(-radiusX, -radiusY);
|
||||
dst.fRowBytes = SkTo<uint32_t>(dstW);
|
||||
}
|
||||
|
||||
dst.fImage = nullptr;
|
||||
dst.fFormat = SkMask::kA8_Format;
|
||||
|
||||
size_t toAlloc = safe.mul(dstW, dstH);
|
||||
|
||||
if (safe && src.fImage != nullptr) {
|
||||
// We can only deal with masks that fit in INT_MAX and sides that fit in int.
|
||||
if (!SkTFitsIn<int>(dstW) || !SkTFitsIn<int>(dstH) || toAlloc > INT_MAX || !safe) {
|
||||
dst.fBounds.setEmpty();
|
||||
dst.fRowBytes = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
dst.fBounds.setWH(SkTo<int>(dstW), SkTo<int>(dstH));
|
||||
dst.fBounds.offset(src.fBounds.x(), src.fBounds.y());
|
||||
dst.fBounds.offset(-radiusX, -radiusY);
|
||||
dst.fRowBytes = SkTo<uint32_t>(dstW);
|
||||
|
||||
if (src.fImage != nullptr) {
|
||||
dst.fImage = SkMask::AllocImage(toAlloc);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user