Region Op Fuzzer

Also: assert Region IRects don't contain Sentinel value.
Also: Region fuzzer can't produce Sentinel value.

Change-Id: Ia33c7eeb9ef2c46b3da4a025d85de8a0406c3c0c
Reviewed-on: https://skia-review.googlesource.com/119011
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
Hal Canary 2018-04-06 10:25:12 -04:00 committed by Skia Commit-Bot
parent 4c2393493a
commit 13872ddc56
5 changed files with 42 additions and 13 deletions

View File

@ -1767,6 +1767,7 @@ if (skia_enable_tools) {
"fuzz/FuzzParsePath.cpp",
"fuzz/FuzzPathMeasure.cpp",
"fuzz/FuzzPathop.cpp",
"fuzz/FuzzRegionOp.cpp",
"fuzz/fuzz.cpp",
"fuzz/oss_fuzz/FuzzAnimatedImage.cpp",
"fuzz/oss_fuzz/FuzzImage.cpp",

View File

@ -76,12 +76,6 @@
// SkTextBlob with Unicode
// SkImage: more types
template <typename T, typename Min, typename Max>
inline void fuzz_enum_range(Fuzz* fuzz, T* value, Min rmin, Max rmax) {
using U = skstd::underlying_type_t<T>;
fuzz->nextRange((U*)value, (U)rmin, (U)rmax);
}
// be careful: `foo(make_fuzz_t<T>(f), make_fuzz_t<U>(f))` is undefined.
// In fact, all make_fuzz_foo() functions have this potential problem.
// Use sequence points!

View File

@ -26,22 +26,34 @@ inline void fuzz_nice_float(Fuzz* fuzz, float* f, Args... rest) {
fuzz_nice_float(fuzz, rest...);
}
template <>
inline void Fuzz::next(SkRegion* region) {
template <typename T, typename Min, typename Max>
inline void fuzz_enum_range(Fuzz* fuzz, T* value, Min rmin, Max rmax) {
using U = skstd::underlying_type_t<T>;
fuzz->nextRange((U*)value, (U)rmin, (U)rmax);
}
inline void fuzz_region(Fuzz* fuzz, SkRegion* region, int maxN) {
uint8_t N;
this->nextRange(&N, 0, 10);
fuzz->nextRange(&N, 0, maxN);
for (uint8_t i = 0; i < N; ++i) {
SkIRect r;
uint8_t op;
this->next(&r);
SkRegion::Op op;
// Avoid the sentinal value used by Region.
fuzz->nextRange(&r.fLeft, -2147483646, 2147483646);
fuzz->nextRange(&r.fTop, -2147483646, 2147483646);
fuzz->nextRange(&r.fRight, -2147483646, 2147483646);
fuzz->nextRange(&r.fBottom, -2147483646, 2147483646);
r.sort();
this->nextRange(&op, 0, (uint8_t)SkRegion::kLastOp);
if (!region->op(r, (SkRegion::Op)op)) {
fuzz_enum_range(fuzz, &op, (SkRegion::Op)0, SkRegion::kLastOp);
if (!region->op(r, op)) {
return;
}
}
}
template <>
inline void Fuzz::next(SkRegion* region) { fuzz_region(this, region, 10); }
// allows some float values for path points
void FuzzPath(Fuzz* fuzz, SkPath* path, int maxOps);
// allows all float values for path points

18
fuzz/FuzzRegionOp.cpp Normal file
View File

@ -0,0 +1,18 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Fuzz.h"
#include "FuzzCommon.h"
DEF_FUZZ(RegionOp, fuzz) { // `fuzz -t api -n RegionOp`
SkRegion regionA, regionB, regionC;
fuzz_region(fuzz, &regionA, 2000);
fuzz_region(fuzz, &regionB, 2000);
SkRegion::Op op;
fuzz_enum_range(fuzz, &op, (SkRegion::Op)0, SkRegion::kLastOp);
regionC.op(regionA, regionB, op);
}

View File

@ -145,6 +145,10 @@ bool SkRegion::setRect(const SkIRect& r) {
return this->setEmpty();
}
this->freeRuns();
SkASSERT(r.left() != SkRegion::kRunTypeSentinel);
SkASSERT(r.top() != SkRegion::kRunTypeSentinel);
SkASSERT(r.right() != SkRegion::kRunTypeSentinel);
SkASSERT(r.bottom() != SkRegion::kRunTypeSentinel);
fBounds = r;
fRunHead = SkRegion_gRectRunHeadPtr;
return true;