aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2016-12-13 09:42:20 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-13 15:22:27 +0000
commit72245c522ab65593239f2056df16082edb4e0a2e (patch)
tree3783f55914859d1c317b58126521a7c851cfa822
parent941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9 (diff)
Avoid int64 overflow in SkClampRange
Update sk_64_smul_check to detect the numeric_limits<int64_t>::min() case (which cannot be safely passed to SkTAbs), and fail. BUG=skia:6019 R=reed@google.com,mtklein@google.com Change-Id: I5f252be7e9377d3261f992b53f2b893899cbe960 Reviewed-on: https://skia-review.googlesource.com/5863 Reviewed-by: Mike Klein <mtklein@chromium.org> Commit-Queue: Florin Malita <fmalita@chromium.org>
-rw-r--r--src/effects/gradients/SkClampRange.cpp15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/effects/gradients/SkClampRange.cpp b/src/effects/gradients/SkClampRange.cpp
index 5fd1c0369e..f820a03710 100644
--- a/src/effects/gradients/SkClampRange.cpp
+++ b/src/effects/gradients/SkClampRange.cpp
@@ -18,18 +18,23 @@ static int SkCLZ64(uint64_t value) {
return count + SkCLZ(SkToU32(value));
}
-static bool sk_64_smul_check(int64_t a, int64_t b, int64_t* result) {
+static bool sk_64_smul_check(int64_t count, int64_t dx, int64_t* result) {
// Do it the slow way until we have some assembly.
- int64_t ua = SkTAbs(a);
- int64_t ub = SkTAbs(b);
- int zeros = SkCLZ64(ua) + SkCLZ64(ub);
+ if (dx == std::numeric_limits<int64_t>::min()) {
+ return false; // SkTAbs overflow
+ }
+
+ SkASSERT(count >= 0);
+ uint64_t ucount = static_cast<uint64_t>(count);
+ uint64_t udx = static_cast<uint64_t>(SkTAbs(dx));
+ int zeros = SkCLZ64(ucount) + SkCLZ64(udx);
// this is a conservative check: it may return false when in fact it would not have overflowed.
// Hackers Delight uses 34 as its convervative check, but that is for 32x32 multiplies.
// Since we are looking at 64x64 muls, we add 32 to the check.
if (zeros < (32 + 34)) {
return false;
}
- *result = a * b;
+ *result = count * dx;
return true;
}