From 03013084aac29967ee0559efce817b39234f4aa6 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Tue, 18 Apr 2017 13:47:15 -0400 Subject: [PATCH] Fix SkATan2_255 fuzzer crash 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 Commit-Queue: Florin Malita --- src/effects/gradients/SkSweepGradient.cpp | 9 ++++-- tests/GradientTest.cpp | 46 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp index 27517bb..23f77b3 100644 --- a/src/effects/gradients/SkSweepGradient.cpp +++ b/src/effects/gradients/SkSweepGradient.cpp @@ -9,6 +9,7 @@ #include "SkSweepGradient.h" #include +#include 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))); diff --git a/tests/GradientTest.cpp b/tests/GradientTest.cpp index ec2753d..732bfbc 100644 --- a/tests/GradientTest.cpp +++ b/tests/GradientTest.cpp @@ -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 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); } -- 2.7.4