aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkRegion.cpp
diff options
context:
space:
mode:
authorGravatar Hal Canary <halcanary@google.com>2017-06-20 11:22:51 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-21 16:59:03 +0000
commit711450e948b9900011dc0d474f82bf7bc9913259 (patch)
tree407cb28f9cf02a4ba222699fcf1bf15be60ff214 /src/core/SkRegion.cpp
parent7da6dfabc44891c51dedcb4754477b662d8c8a0a (diff)
SkRegion: more robust validation
BUG=oss-fuzz:1864 Change-Id: I4c3d3c4c7b0717399fe16f227e032682b13ebc74 Reviewed-on: https://skia-review.googlesource.com/20322 Reviewed-by: Cary Clark <caryclark@google.com> Commit-Queue: Hal Canary <halcanary@google.com>
Diffstat (limited to 'src/core/SkRegion.cpp')
-rw-r--r--src/core/SkRegion.cpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/core/SkRegion.cpp b/src/core/SkRegion.cpp
index e873ebb453..b25633b67c 100644
--- a/src/core/SkRegion.cpp
+++ b/src/core/SkRegion.cpp
@@ -1155,6 +1155,9 @@ static bool validate_run(const int32_t* runs,
if (rect.fTop == SkRegion::kRunTypeSentinel) {
return false; // no rect can contain SkRegion::kRunTypeSentinel
}
+ if (rect.fTop != givenBounds.fTop) {
+ return false; // Must not begin with empty span that does not contribute to bounds.
+ }
do {
--ySpanCount;
if (ySpanCount < 0) {
@@ -1164,6 +1167,13 @@ static bool validate_run(const int32_t* runs,
if (rect.fBottom == SkRegion::kRunTypeSentinel) {
return false;
}
+ if (rect.fBottom > givenBounds.fBottom) {
+ return false; // Must not end with empty span that does not contribute to bounds.
+ }
+ if (rect.fBottom <= rect.fTop) {
+ return false; // y-intervals must be ordered; rects must be non-empty.
+ }
+
int32_t xIntervals = *runs++;
SkASSERT(runs < end);
if (xIntervals < 0 || runs + 1 + 2 * xIntervals > end) {
@@ -1173,13 +1183,19 @@ static bool validate_run(const int32_t* runs,
if (intervalCount < 0) {
return false; // too many intervals
}
+ bool firstInterval = true;
+ int32_t lastRight; // check that x-intervals are distinct and ordered.
while (xIntervals-- > 0) {
rect.fLeft = *runs++;
rect.fRight = *runs++;
if (rect.fLeft == SkRegion::kRunTypeSentinel ||
- rect.fRight == SkRegion::kRunTypeSentinel || rect.isEmpty()) {
+ rect.fRight == SkRegion::kRunTypeSentinel ||
+ rect.fLeft >= rect.fRight || // check non-empty rect
+ (!firstInterval && rect.fLeft <= lastRight)) {
return false;
}
+ lastRight = rect.fRight;
+ firstInterval = false;
bounds.join(rect);
}
if (*runs++ != SkRegion::kRunTypeSentinel) {