aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkScan_AAAPath.cpp
diff options
context:
space:
mode:
authorGravatar Yuqian Li <liyuqian@google.com>2016-11-14 16:45:01 -0500
committerGravatar Mike Klein <mtklein@chromium.org>2016-11-14 23:08:21 +0000
commit06196411cb3e06bd041b7ec12e69d0a7a790d5b7 (patch)
tree0dcd15190402b969b29b60000321a57ceaaf8189 /src/core/SkScan_AAAPath.cpp
parent662c2aed38c1917c05883095a8013f51931aafa4 (diff)
Catch width overflow in ASAN using int64
This is related with our previous CL: https://skia-review.googlesource.com/c/4628/ That previous CL fix won't pass the ASAN test (../../../include/core/SkRect.h:72:39: runtime error: signed integer overflow: 1 - -2147483648 cannot be represented in type 'int') so we use int64 in this CL. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4785 Change-Id: I39f7329c427d49f4be07588f37120722ac9892c2 Reviewed-on: https://skia-review.googlesource.com/4785 Reviewed-by: Mike Reed <reed@google.com>
Diffstat (limited to 'src/core/SkScan_AAAPath.cpp')
-rw-r--r--src/core/SkScan_AAAPath.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/core/SkScan_AAAPath.cpp b/src/core/SkScan_AAAPath.cpp
index 8ca2fea714..3915feae59 100644
--- a/src/core/SkScan_AAAPath.cpp
+++ b/src/core/SkScan_AAAPath.cpp
@@ -153,8 +153,7 @@ public:
int getWidth() override { return fClipRect.width(); }
static bool canHandleRect(const SkIRect& bounds) {
- // The width may overflow signed int, e.g., left = -2147483648, right = 1
- unsigned width = bounds.width();
+ int width = bounds.width();
if (width > MaskAdditiveBlitter::kMAX_WIDTH) {
return false;
}
@@ -1251,6 +1250,22 @@ static int rect_overflows_short_shift(SkIRect rect, int shift) {
overflows_short_shift(rect.fBottom, 2);
}
+static bool fitsInsideLimit(const SkRect& r, SkScalar max) {
+ const SkScalar min = -max;
+ return r.fLeft > min && r.fTop > min &&
+ r.fRight < max && r.fBottom < max;
+}
+
+static bool safeRoundOut(const SkRect& src, SkIRect* dst, int32_t maxInt) {
+ const SkScalar maxScalar = SkIntToScalar(maxInt);
+
+ if (fitsInsideLimit(src, maxScalar)) {
+ src.roundOut(dst);
+ return true;
+ }
+ return false;
+}
+
void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter* blitter,
bool forceRLE) {
if (origClip.isEmpty()) {
@@ -1264,7 +1279,9 @@ void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter
const bool isInverse = path.isInverseFillType();
SkIRect ir;
- path.getBounds().roundOut(&ir);
+ if (!safeRoundOut(path.getBounds(), &ir, SK_MaxS32 >> 2)) {
+ return;
+ }
if (ir.isEmpty()) {
if (isInverse) {
blitter->blitRegion(origClip);