Fix SkATan2_255 fuzzer crash
authorFlorin Malita <fmalita@chromium.org>
Tue, 18 Apr 2017 17:47:15 +0000 (13:47 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 19 Apr 2017 17:33:08 +0000 (17:33 +0000)
Test for degenerate values after computing the ratio, instead of
attempting to catch all tricky cases upfront.

BUG=skia:6511

Change-Id: I8e3421675994dd68a1eff1af3f1456917dd1f9e1
Reviewed-on: https://skia-review.googlesource.com/13726
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>

src/effects/gradients/SkSweepGradient.cpp
tests/GradientTest.cpp

index 27517bb..23f77b3 100644 (file)
@@ -9,6 +9,7 @@
 #include "SkSweepGradient.h"
 
 #include <algorithm>
+#include <cmath>
 
 static SkMatrix translate(SkScalar dx, SkScalar dy) {
     SkMatrix matrix;
@@ -80,12 +81,16 @@ static unsigned SkATan2_255(float y, float x) {
 }
 #else
 static unsigned SkATan2_255(float y, float x) {
-    if (y == 0 && x == 0) return 0;
     float yabs = sk_float_abs(y),
-        xabs = sk_float_abs(x);
+          xabs = sk_float_abs(x);
     float little, big;
     std::tie(little, big) = std::minmax(yabs, xabs);
     float a = little/big;
+    if (!std::isfinite(a)) {
+        return 0;
+    }
+    SkASSERT(a >=0 && a <= 1);
+
     float s = a * a;
     float r = a*(40.57589784014689f
                  + s*(-13.222755844396332f + s*(6.314046289038564f - s*1.7989502668982151f)));
index ec2753d..732bfbc 100644 (file)
@@ -480,6 +480,51 @@ static void test_linear_fuzzer(skiatest::Reporter*) {
     }
 }
 
+static void test_sweep_fuzzer(skiatest::Reporter*) {
+    static const SkColor gColors0[] = { 0x30303030, 0x30303030, 0x30303030 };
+    static const SkScalar   gPos0[] = { -47919293023455565225163489280.0f, 0, 1 };
+    static const SkScalar gMatrix0[9] = {
+        1.12116716e-13f,  0              ,  8.50489682e+16f,
+        4.1917041e-41f ,  3.51369881e-23f, -2.54344271e-26f,
+        9.61111907e+17f, -3.35263808e-29f, -1.35659403e+14f
+    };
+    static const struct {
+        SkPoint            fCenter;
+        const SkColor*     fColors;
+        const SkScalar*    fPos;
+        int                fCount;
+        const SkScalar*    fGlobalMatrix;
+    } gConfigs[] = {
+        {
+            { 0, 0 },
+            gColors0,
+            gPos0,
+            SK_ARRAY_COUNT(gColors0),
+            gMatrix0
+        },
+    };
+
+    sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(100, 100);
+    SkCanvas* canvas = surface->getCanvas();
+    SkPaint paint;
+
+    for (const auto& config : gConfigs) {
+        paint.setShader(SkGradientShader::MakeSweep(config.fCenter.x(),
+                                                    config.fCenter.y(),
+                                                    config.fColors,
+                                                    config.fPos,
+                                                    config.fCount));
+
+        SkAutoCanvasRestore acr(canvas, false);
+        if (config.fGlobalMatrix) {
+            SkMatrix m;
+            m.set9(config.fGlobalMatrix);
+            canvas->save();
+            canvas->concat(m);
+        }
+        canvas->drawPaint(paint);
+    }
+}
 
 DEF_TEST(Gradient, reporter) {
     TestGradientShaders(reporter);
@@ -493,4 +538,5 @@ DEF_TEST(Gradient, reporter) {
     test_clamping_overflow(reporter);
     test_degenerate_linear(reporter);
     test_linear_fuzzer(reporter);
+    test_sweep_fuzzer(reporter);
 }