diff options
-rw-r--r-- | src/core/SkRegion.cpp | 18 | ||||
-rw-r--r-- | tests/RegionTest.cpp | 32 |
2 files changed, 49 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) { diff --git a/tests/RegionTest.cpp b/tests/RegionTest.cpp index 2a5d0a5059..7fcf1014f7 100644 --- a/tests/RegionTest.cpp +++ b/tests/RegionTest.cpp @@ -328,6 +328,13 @@ DEF_TEST(Region_readFromMemory_bad, r) { REPORTER_ASSERT(r, 0 != region.readFromMemory(data, sizeof(data))); } { + // Example of valid data with 4 intervals + int32_t data[] = {19, 0, 0, 30, 30, 3, 4, 0, 10, 2, 0, 10, 20, 30, + 2147483647, 20, 0, 2147483647, 30, 2, 0, 10, 20, 30, + 2147483647, 2147483647}; + REPORTER_ASSERT(r, 0 != region.readFromMemory(data, sizeof(data))); + } + { // Short count int32_t data[] = {8, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10, 2147483647, 2147483647}; @@ -363,4 +370,29 @@ DEF_TEST(Region_readFromMemory_bad, r) { -1, 2147483647}; REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data))); } + { + // starts with empty yspan + int32_t data[] = {12, 0, 0, 10, 10, 2, 2, -5, 0, 0, 2147483647, 10, + 2, 0, 4, 6, 10, 2147483647, 2147483647}; + REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data))); + } + { + // ends with empty yspan + int32_t data[] = {12, 0, 0, 10, 10, 2, 2, 0, 10, 2, 0, 4, 6, 10, + 2147483647, 15, 0, 2147483647, 2147483647}; + REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data))); + } + { + // y intervals out of order + int32_t data[] = {19, 0, -20, 30, 10, 3, 4, 0, 10, 2, 0, 10, 20, 30, + 2147483647, -20, 0, 2147483647, -10, 2, 0, 10, 20, 30, + 2147483647, 2147483647}; + REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data))); + } + { + // x intervals out of order + int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 6, 10, 0, 4, + 2147483647, 2147483647}; + REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data))); + } } |