aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/effects/gradients/SkClampRange.cpp23
-rw-r--r--tests/GradientTest.cpp48
2 files changed, 59 insertions, 12 deletions
diff --git a/src/effects/gradients/SkClampRange.cpp b/src/effects/gradients/SkClampRange.cpp
index f820a03710..efc93959d1 100644
--- a/src/effects/gradients/SkClampRange.cpp
+++ b/src/effects/gradients/SkClampRange.cpp
@@ -38,6 +38,22 @@ static bool sk_64_smul_check(int64_t count, int64_t dx, int64_t* result) {
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
@@ -87,16 +103,15 @@ void SkClampRange::init(SkGradFixed fx0, SkGradFixed dx0, int count, int v0, int
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;
diff --git a/tests/GradientTest.cpp b/tests/GradientTest.cpp
index 4cdd0c94bc..e46bfb46c6 100644
--- a/tests/GradientTest.cpp
+++ b/tests/GradientTest.cpp
@@ -374,14 +374,26 @@ static void test_linear_fuzzer(skiatest::Reporter*) {
static const SkScalar gPos1[] = { 0, 0, 1 };
- static const SkScalar gMatrix0[9] =
- { 6.40969056e-10f, 0 , 6.40969056e-10f,
- 0 , 4.42539023e-39f, 6.40969056e-10f,
- 0 , 0 , 1 };
- static const SkScalar gMatrix1[9] =
- { -2.75294113f , 6.40969056e-10f, 6.40969056e-10f,
- 6.40969056e-10f, 6.40969056e-10f, -3.32810161e+24f,
- 6.40969056e-10f, 6.40969056e-10f, 0 };
+ static const SkScalar gMatrix0[9] = {
+ 6.40969056e-10f, 0 , 6.40969056e-10f,
+ 0 , 4.42539023e-39f, 6.40969056e-10f,
+ 0 , 0 , 1
+ };
+ static const SkScalar gMatrix1[9] = {
+ -2.75294113f , 6.40969056e-10f, 6.40969056e-10f,
+ 6.40969056e-10f, 6.40969056e-10f, -3.32810161e+24f,
+ 6.40969056e-10f, 6.40969056e-10f, 0
+ };
+ static const SkScalar gMatrix2[9] = {
+ 7.93481258e+17f, 6.40969056e-10f, 6.40969056e-10f,
+ 6.40969056e-10f, 6.40969056e-10f, 6.40969056e-10f,
+ 6.40969056e-10f, 6.40969056e-10f, 0.688235283f
+ };
+ static const SkScalar gMatrix3[9] = {
+ 1.89180674e+11f, 6.40969056e-10f, 6.40969056e-10f,
+ 6.40969056e-10f, 6.40969056e-10f, 6.40969056e-10f,
+ 6.40969056e-10f, 11276.0469f , 8.12524808e+20f
+ };
static const struct {
SkPoint fPts[2];
@@ -413,6 +425,26 @@ static void test_linear_fuzzer(skiatest::Reporter*) {
nullptr,
gMatrix1
},
+ {
+ {{4.42539023e-39f, 6.40969056e-10f}, {6.40969056e-10f, 1.49237238e-19f}},
+ gColors1,
+ gPos1,
+ SK_ARRAY_COUNT(gColors1),
+ SkShader::kClamp_TileMode,
+ 0,
+ nullptr,
+ gMatrix2
+ },
+ {
+ {{6.40969056e-10f, 6.40969056e-10f}, {6.40969056e-10f, -0.688235283f}},
+ gColors0,
+ nullptr,
+ SK_ARRAY_COUNT(gColors0),
+ SkShader::kClamp_TileMode,
+ 0,
+ gMatrix3,
+ nullptr
+ },
};
static const uint32_t gForceFlags[] = { 0, SkLinearGradient::kForce4fContext_PrivateFlag };