aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-05-24 10:39:57 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-24 15:16:43 +0000
commitd2e74b8080e9ea3b0aac371d4c75190d55b151eb (patch)
tree9c7cdaf673b8af704a33101582167a88f522d671
parent75bf216c033896ffeff5176e8b5f5fb79c02f8fb (diff)
compute center slightly slower to avoid overflow
Bug: oss-fuzz:8509 Change-Id: I13b1a77e1549070827a7cc534b062ec85aad255e Reviewed-on: https://skia-review.googlesource.com/129930 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
-rw-r--r--include/core/SkRect.h10
-rw-r--r--tests/RectTest.cpp21
2 files changed, 29 insertions, 2 deletions
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index 2a46da68c6..920572f317 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -931,14 +931,20 @@ struct SK_API SkRect {
@return midpoint in x
*/
- SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); }
+ SkScalar centerX() const {
+ // don't use SkScalarHalf(fLeft + fBottom) as that might overflow before the 0.5
+ return SkScalarHalf(fLeft) + SkScalarHalf(fRight);
+ }
/** Returns average of top edge and bottom edge. Result does not change if SkRect
is sorted. Result may overflow to infinity if SkRect is far from the origin.
@return midpoint in y
*/
- SkScalar centerY() const { return SkScalarHalf(fTop + fBottom); }
+ SkScalar centerY() const {
+ // don't use SkScalarHalf(fTop + fBottom) as that might overflow before the 0.5
+ return SkScalarHalf(fTop) + SkScalarHalf(fBottom);
+ }
/** Returns true if all members in a: fLeft, fTop, fRight, and fBottom; are
equal to the corresponding members in b.
diff --git a/tests/RectTest.cpp b/tests/RectTest.cpp
index 7d2601a8be..2594c53cac 100644
--- a/tests/RectTest.cpp
+++ b/tests/RectTest.cpp
@@ -139,3 +139,24 @@ DEF_TEST(Rect_setbounds, reporter) {
}
}
}
+
+static float make_big_value(skiatest::Reporter* reporter) {
+ // need to make a big value, one that will cause rect.width() to overflow to inf.
+ // however, the windows compiler wants about this if it can see the big value inlined.
+ // hence, this stupid trick to try to fool their compiler.
+ SkASSERT(reporter);
+ return reporter ? SK_ScalarMax * 0.75f : 0;
+}
+
+DEF_TEST(Rect_center, reporter) {
+ // ensure we can compute center even when the width/height might overflow
+ const SkScalar big = make_big_value(reporter);
+ const SkRect r = { -big, -big, big, big };
+
+ REPORTER_ASSERT(reporter, r.isFinite());
+ REPORTER_ASSERT(reporter, SkScalarIsFinite(r.centerX()));
+ REPORTER_ASSERT(reporter, SkScalarIsFinite(r.centerY()));
+ REPORTER_ASSERT(reporter, !SkScalarIsFinite(r.width()));
+ REPORTER_ASSERT(reporter, !SkScalarIsFinite(r.height()));
+}
+