aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-03-21 16:17:10 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-02 15:15:25 +0000
commit9b8b0cee513bc242553f1639a28c3638f568842e (patch)
tree3c5efc4f728fefa532f2e8a5583c6ee57a9dd59b /src/core
parent01a1cf92603c048c81dec419177e4e5f76be50f6 (diff)
fix SkRRect fuzzer assert
fuzzer bug triggers an assert in SkRRect::isValid because on radius is zero and the other, while small, is not. The radii are normally both set to zero if one is zero in SkRRect::setRectRadii. However, subsequently scaleRadii may set one to zero when normalizing the pair. Move the clamping code out of setRectRadii so it can be called from scaleRadii as well. R=reed@google.com Bug: skia: Change-Id: Ib9a86da7212567b2f4b83d99a41cf9ba2c30e9b9 Reviewed-on: https://skia-review.googlesource.com/115701 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Cary Clark <caryclark@google.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkRRect.cpp48
1 files changed, 29 insertions, 19 deletions
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp
index a8ed7246ef..50a87fab3c 100644
--- a/src/core/SkRRect.cpp
+++ b/src/core/SkRRect.cpp
@@ -116,40 +116,44 @@ static double compute_min_scale(double rad1, double rad2, double limit, double c
return curMin;
}
-void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) {
- if (!this->initializeRect(rect)) {
- return;
- }
-
- if (!SkScalarsAreFinite(&radii[0].fX, 8)) {
- this->setRect(rect); // devolve into a simple rect
- return;
- }
-
- memcpy(fRadii, radii, sizeof(fRadii));
-
+static bool clamp_to_zero(SkVector radii[4]) {
bool allCornersSquare = true;
// Clamp negative radii to zero
for (int i = 0; i < 4; ++i) {
- if (fRadii[i].fX <= 0 || fRadii[i].fY <= 0) {
+ if (radii[i].fX <= 0 || radii[i].fY <= 0) {
// In this case we are being a little fast & loose. Since one of
// the radii is 0 the corner is square. However, the other radii
// could still be non-zero and play in the global scale factor
// computation.
- fRadii[i].fX = 0;
- fRadii[i].fY = 0;
+ radii[i].fX = 0;
+ radii[i].fY = 0;
} else {
allCornersSquare = false;
}
}
- if (allCornersSquare) {
+ return allCornersSquare;
+}
+
+void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) {
+ if (!this->initializeRect(rect)) {
+ return;
+ }
+
+ if (!SkScalarsAreFinite(&radii[0].fX, 8)) {
+ this->setRect(rect); // devolve into a simple rect
+ return;
+ }
+
+ memcpy(fRadii, radii, sizeof(fRadii));
+
+ if (clamp_to_zero(fRadii)) {
this->setRect(rect);
return;
}
- this->scaleRadii();
+ this->scaleRadii(rect);
}
bool SkRRect::initializeRect(const SkRect& rect) {
@@ -167,7 +171,7 @@ bool SkRRect::initializeRect(const SkRect& rect) {
return true;
}
-void SkRRect::scaleRadii() {
+void SkRRect::scaleRadii(const SkRect& rect) {
// Proportionally scale down all radii to fit. Find the minimum ratio
// of a side and the radii on that side (for all four sides) and use
@@ -196,6 +200,12 @@ void SkRRect::scaleRadii() {
SkScaleToSides::AdjustRadii(height, scale, &fRadii[3].fY, &fRadii[0].fY);
}
+ // adjust radii may set x or y to zero; set companion to zero as well
+ if (clamp_to_zero(fRadii)) {
+ this->setRect(rect);
+ return;
+ }
+
// At this point we're either oval, simple, or complex (not empty or rect).
this->computeType();
@@ -440,7 +450,7 @@ bool SkRRect::transform(const SkMatrix& matrix, SkRRect* dst) const {
return false;
}
- dst->scaleRadii();
+ dst->scaleRadii(dst->fRect);
dst->isValid();
return true;