aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-04-17 09:30:14 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-17 13:50:13 +0000
commita7651567ca7e5462de993f1b23d681c6171bcccf (patch)
tree11d2f27bb78b83528b7e3918a6d558dd5ee6b452
parent8954d097c35296d2b33293e65552cc3de39c5d2a (diff)
yet another path is rect exploit
This one accumulates the othershoot when all four sides have the same direction, and the final side when closed should cause the overshoot to be ignored. Docs-Preview: https://skia.org/?cl=121787 Bug: 824145,skia:7792 Change-Id: I71ea0fcdd0f03a4fcac224b57220c65c321112f6 Reviewed-on: https://skia-review.googlesource.com/121787 Commit-Queue: Cary Clark <caryclark@skia.org> Commit-Queue: Robert Phillips <robertphillips@google.com> Auto-Submit: Cary Clark <caryclark@skia.org> Reviewed-by: Robert Phillips <robertphillips@google.com>
-rw-r--r--gm/pathfill.cpp11
-rw-r--r--src/core/SkPath.cpp7
-rw-r--r--tests/PathTest.cpp9
3 files changed, 26 insertions, 1 deletions
diff --git a/gm/pathfill.cpp b/gm/pathfill.cpp
index cb878abe14..0fcffdc23f 100644
--- a/gm/pathfill.cpp
+++ b/gm/pathfill.cpp
@@ -547,4 +547,15 @@ DEF_SIMPLE_GM(bug7792, canvas, 600, 800) {
path.moveTo(75, 75);
path.close();
canvas->drawPath(path, p);
+ // from skbug.com/7792#c31
+ canvas->translate(200, 0);
+ path.reset();
+ path.moveTo(75, 75);
+ path.lineTo(150, 75);
+ path.lineTo(150, 150);
+ path.lineTo(75, 150);
+ path.lineTo(75, 10);
+ path.moveTo(75, 75);
+ path.close();
+ canvas->drawPath(path, p);
}
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index d5538f7780..0ff5edf109 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -453,6 +453,7 @@ bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts
SkPoint lineStart; // used to construct line from previous point
const SkPoint* firstPt = nullptr; // first point in the rect (last of first moves)
const SkPoint* lastPt = nullptr; // last point in the rect (last of lines or first if closed)
+ const SkPoint* lastCountedPt = nullptr; // point creating 3rd corner
const SkPoint* pts = *ptsPtr;
const SkPoint* savePts = nullptr; // used to allow caller to iterate through a pair of rects
lineStart.set(0, 0);
@@ -473,6 +474,9 @@ bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts
accumulatingRect = false;
case kLine_Verb: {
if (accumulatingRect) {
+ lastCountedPt = pts;
+ }
+ if (kClose_Verb != verb) {
lastPt = pts;
}
SkPoint lineEnd = kClose_Verb == verb ? *firstPt : *pts++;
@@ -512,6 +516,7 @@ bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts
if ((directions[0] ^ directions[2]) != 2) {
return false;
}
+ accumulatingRect = false;
} else if (corners == 4) {
if ((directions[1] ^ directions[3]) != 2) {
return false;
@@ -574,7 +579,7 @@ addMissingClose:
*ptsPtr = savePts;
}
if (result && rect) {
- ptrdiff_t count = lastPt - firstPt + 1;
+ ptrdiff_t count = lastCountedPt - firstPt + 1;
rect->set(firstPt, (int) count);
}
if (result && isClosed) {
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index 38b5bf7424..817aa82b75 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -5003,4 +5003,13 @@ DEF_TEST(Path_isRect, reporter) {
SkPoint points29[] = { {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 250}, {75, 75} };
path = makePath2(points29, verbs29, SK_ARRAY_COUNT(verbs29));
REPORTER_ASSERT(reporter, !path.isRect(&rect, nullptr, nullptr));
+ // isolated from skbug.com/7792#c31
+ SkPath::Verb verbs31[] = { SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb,
+ SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kMove_Verb,
+ SkPath::kClose_Verb };
+ SkPoint points31[] = { {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 10}, {75, 75} };
+ path = makePath2(points31, verbs31, SK_ARRAY_COUNT(verbs31));
+ REPORTER_ASSERT(reporter, path.isRect(&rect, nullptr, nullptr));
+ compare.set(&points31[0], 4);
+ REPORTER_ASSERT(reporter, rect == compare);
}