aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkRegion.cpp
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-04-30 17:05:15 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-01 15:29:14 +0000
commitdc3192b30a9e42aea8ff8d0c01ea585c79902704 (patch)
tree32324a64ed2846e9ccf81980f777e3178b8c52c9 /src/core/SkRegion.cpp
parentff8387fae47e482c6f78865deb2746618a51fa51 (diff)
pin offset request before applying to region
Bug: oss-fuzz:8085 Change-Id: I2e19250822a6ffc3d68a474c8eb4cca0ea66c991 Reviewed-on: https://skia-review.googlesource.com/124700 Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src/core/SkRegion.cpp')
-rw-r--r--src/core/SkRegion.cpp21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/core/SkRegion.cpp b/src/core/SkRegion.cpp
index bf06e747db..080b148e47 100644
--- a/src/core/SkRegion.cpp
+++ b/src/core/SkRegion.cpp
@@ -574,6 +574,16 @@ bool SkRegion::operator==(const SkRegion& b) const {
ah->fRunCount * sizeof(SkRegion::RunType));
}
+// Return a (new) offset such that when applied (+=) to min and max, we don't overflow/underflow
+static int32_t pin_offset_s32(int32_t min, int32_t max, int32_t offset) {
+ SkASSERT(min <= max);
+ const int32_t lo = -SK_MaxS32-1,
+ hi = +SK_MaxS32;
+ if ((int64_t)min + offset < lo) { offset = lo - min; }
+ if ((int64_t)max + offset > hi) { offset = hi - max; }
+ return offset;
+}
+
void SkRegion::translate(int dx, int dy, SkRegion* dst) const {
SkDEBUGCODE(this->validate();)
@@ -582,9 +592,14 @@ void SkRegion::translate(int dx, int dy, SkRegion* dst) const {
}
if (this->isEmpty()) {
dst->setEmpty();
- } else if (this->isRect()) {
- dst->setRect(fBounds.fLeft + dx, fBounds.fTop + dy,
- fBounds.fRight + dx, fBounds.fBottom + dy);
+ return;
+ }
+ // pin dx and dy so we don't overflow our existing bounds
+ dx = pin_offset_s32(fBounds.fLeft, fBounds.fRight, dx);
+ dy = pin_offset_s32(fBounds.fTop, fBounds.fBottom, dy);
+
+ if (this->isRect()) {
+ dst->setRect(fBounds.makeOffset(dx, dy));
} else {
if (this == dst) {
dst->fRunHead = dst->fRunHead->ensureWritable();