skia2/fuzz/FuzzTriangulation.cpp
Michael Ludwig 799658f5c2 More sanitization of coordinates in GrTriangulator
It took a few "independent" changes in order to get the linked fuzzer
bugs to pass without failing. Leaving any out triggered an issue :/

 1. I changed nearly_flat to be <= epsilon, since if it's == epsilon and
    we split the edge, then the new coordinates would have
    difference < epsilon.
 2. I updated double_to_clamped_scalar to also snap very small values to
    0 (right now 16 * float epsilon).
 3. double_to_clamped_scalar is now used to clean up the computed
    intersection of two edges, and is used to process all initial
    vertices (in case the curve evaluation generates lots of denormals
    etc.)
 4. I updated the use of nearly_flat in checkForIntersection to report
    no intersection if both lines are nearly_flat. The comments suggest
    nearly_flat means you can't split along that line since the new
    coord is incalculable. So if both lines are flat, it's a really
    tough numerical scenario and I just punt.

Then I made a few other changes for the fuzzer and debugging:
 1. Added more logging messages and updated the code so that it compiles
    correctly if TRIANGULATOR_LOGGING is defined.
 2. I was also getting asserts in the fuzzer because the vertex
    allocator expects the vertex buffer to be detached by the path
    renderer before its destroyed, so I just have the fuzzer detach and
    discard it. Running locally, the fuzzer test cases from the two
    linked bugs pass successfully without oom'ing or timing out.

Bug: oss-fuzz:33672, oss-fuzz:33620
Change-Id: I7687b920db0a9e200b3fa79b323974b7812e52ff
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404120
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
2021-05-10 15:23:02 +00:00

34 lines
1.0 KiB
C++

/*
* Copyright 2021 Google, LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "fuzz/Fuzz.h"
#include "fuzz/FuzzCommon.h"
#include "include/core/SkPath.h"
#include "src/gpu/GrEagerVertexAllocator.h"
#include "src/gpu/GrTriangulator.h"
#include "src/gpu/geometry/GrPathUtils.h"
DEF_FUZZ(Triangulation, fuzz) {
SkPath path;
FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
SkScalar tol = GrPathUtils::scaleToleranceToSrc(GrPathUtils::kDefaultTolerance,
SkMatrix::I(), path.getBounds());
// TODO(robertphillips): messing w/ the clipBounds might be another axis to fuzz.
// afaict it only affects inverse filled paths.
SkRect clipBounds = path.getBounds();
GrCpuVertexAllocator allocator;
bool isLinear;
GrTriangulator::PathToTriangles(path, tol, clipBounds, &allocator, &isLinear);
allocator.detachVertexData(); // normally handled by the triangulating path renderer.
}