Bug 1339637 - fix overflow in SkClampRange::init(). r=jrmuizel
authorLee Salzman <lsalzman@mozilla.com>
Tue, 21 Feb 2017 14:32:39 -0500
changeset 344154 8568a8c74f309df44b773d3db3444c928403fdf7
parent 344153 a79f71b7d7a3e3d0189b9bcd801ee76548ddcc70
child 344155 fc14157949746f4f5b902e2f1500589a5f60e401
push id31402
push usercbook@mozilla.com
push dateWed, 22 Feb 2017 13:33:50 +0000
treeherdermozilla-central@f5372cb6c3c7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1339637
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1339637 - fix overflow in SkClampRange::init(). r=jrmuizel MozReview-Commit-ID: 7NtQP5QPsFk
gfx/skia/skia/src/effects/gradients/SkClampRange.cpp
--- a/gfx/skia/skia/src/effects/gradients/SkClampRange.cpp
+++ b/gfx/skia/skia/src/effects/gradients/SkClampRange.cpp
@@ -28,16 +28,31 @@ static bool sk_64_smul_check(int64_t a, 
     // Since we are looking at 64x64 muls, we add 32 to the check.
     if (zeros < (32 + 34)) {
         return false;
     }
     *result = a * b;
     return true;
 }
 
+static bool sk_64_sadd_check(int64_t a, int64_t b, int64_t* result) {
+    if (a > 0) {
+        if (b > std::numeric_limits<int64_t>::max() - a) {
+            return false;
+        }
+    } else {
+        if (b < std::numeric_limits<int64_t>::min() - a) {
+            return false;
+        }
+    }
+
+    *result = a + b;
+    return true;
+}
+
 /*
  *  returns [0..count] for the number of steps (<= count) for which x0 <= edge
  *  given each step is followed by x0 += dx
  */
 static int chop(int64_t x0, SkGradFixed edge, int64_t x1, int64_t dx, int count) {
     SkASSERT(dx > 0);
     SkASSERT(count >= 0);
 
@@ -77,26 +92,25 @@ void SkClampRange::init(SkGradFixed fx0,
         this->initFor1(fx0);
         return;
     }
 
     int64_t fx = fx0;
     int64_t dx = dx0;
 
     // start with ex equal to the last computed value
-    int64_t count_times_dx;
-    if (!sk_64_smul_check(count - 1, dx, &count_times_dx)) {
+    int64_t count_times_dx, ex;
+    if (!sk_64_smul_check(count - 1, dx, &count_times_dx) ||
+        !sk_64_sadd_check(fx, count_times_dx, &ex)) {
         // we can't represent the computed end in 32.32, so just draw something (first color)
         fCount1 = fCount2 = 0;
         fCount0 = count;
         return;
     }
 
-    int64_t ex = fx + (count - 1) * dx;
-
     if ((uint64_t)(fx | ex) <= kFracMax_SkGradFixed) {
         fCount0 = fCount2 = 0;
         fCount1 = count;
         fFx1 = fx0;
         return;
     }
     if (fx <= 0 && ex <= 0) {
         fCount1 = fCount2 = 0;