Coverage Report

Created: 2024-09-14 07:19

/src/skia/fuzz/Fuzz.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2016 Google Inc.
3
 *
4
 * Use of this source code is governed by a BSD-style license that can be
5
 * found in the LICENSE file.
6
 */
7
8
#ifndef Fuzz_DEFINED
9
#define Fuzz_DEFINED
10
11
#include "include/core/SkData.h"
12
#include "include/core/SkImageFilter.h"
13
#include "include/core/SkRegion.h"
14
#include "include/core/SkTypes.h"
15
#include "include/private/base/SkMalloc.h"
16
#include "include/private/base/SkTFitsIn.h"
17
#include "tools/Registry.h"
18
19
#include <limits>
20
#include <cmath>
21
#include <signal.h>
22
#include <limits>
23
24
class Fuzz {
25
public:
26
92.4k
    explicit Fuzz(const uint8_t* data, size_t size) : fData(data), fSize(size), fNextByte(0) {}
27
    Fuzz() = delete;
28
29
    // Make noncopyable
30
    Fuzz(Fuzz&) = delete;
31
    Fuzz& operator=(Fuzz&) = delete;
32
33
    // Returns the total number of "random" bytes available.
34
0
    size_t size() const {
35
0
        return fSize;
36
0
    }
37
38
    // Returns if there are no bytes remaining for fuzzing.
39
852k
    bool exhausted() const {
40
852k
        return fSize == fNextByte;
41
852k
    }
42
43
0
    void deplete() {
44
0
        fNextByte = fSize;
45
0
    }
46
47
10.3k
    size_t remainingSize() const {
48
10.3k
        return fSize - fNextByte;
49
10.3k
    }
50
51
10.3k
    const uint8_t *remainingData() const {
52
10.3k
        return fData + fNextByte;
53
10.3k
    }
54
55
    // next() loads fuzzed bytes into the variable passed in by pointer.
56
    // We use this approach instead of T next() because different compilers
57
    // evaluate function parameters in different orders. If fuzz->next()
58
    // returned 5 and then 7, foo(fuzz->next(), fuzz->next()) would be
59
    // foo(5, 7) when compiled on GCC and foo(7, 5) when compiled on Clang.
60
    // By requiring params to be passed in, we avoid the temptation to call
61
    // next() in a way that does not consume fuzzed bytes in a single
62
    // platform-independent order.
63
    template <typename T>
64
375M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkRect>(SkRect*)
Line
Count
Source
64
16.3k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkPoint>(SkPoint*)
Line
Count
Source
64
801k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkISize>(SkISize*)
Line
Count
Source
64
14.0k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<unsigned char>(unsigned char*)
Line
Count
Source
64
10.3M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<int>(int*)
Line
Count
Source
64
1.53M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<float>(float*)
Line
Count
Source
64
5.92M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<unsigned long>(unsigned long*)
Line
Count
Source
64
3.90k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkIRect>(SkIRect*)
Line
Count
Source
64
45.8k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<signed char>(signed char*)
Line
Count
Source
64
3.73k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<unsigned short>(unsigned short*)
Line
Count
Source
64
89.7k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<unsigned int>(unsigned int*)
Line
Count
Source
64
356M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<char>(char*)
Line
Count
Source
64
74.4k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkPoint3>(SkPoint3*)
Line
Count
Source
64
7.88k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
Unexecuted instantiation: void Fuzz::next<char16_t>(char16_t*)
void Fuzz::next<double>(double*)
Line
Count
Source
64
431
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
65
66
    // This is a convenient way to initialize more than one argument at a time.
67
    template <typename Arg, typename... Args>
68
    void next(Arg* first, Args... rest);
69
70
    // nextRange returns values only in [min, max].
71
    template <typename T, typename Min, typename Max>
72
    void nextRange(T*, Min, Max);
73
74
    // nextEnum is a wrapper around nextRange for enums.
75
    template <typename T>
76
    void nextEnum(T* ptr, T max);
77
78
    // nextN loads n * sizeof(T) bytes into ptr
79
    template <typename T>
80
    void nextN(T* ptr, int n);
81
82
0
    void signalBug() {
83
        // Tell the fuzzer that these inputs found a bug.
84
0
        SkDebugf("Signal bug\n");
85
0
        raise(SIGSEGV);
86
0
    }
87
88
    // Specialized versions for when true random doesn't quite make sense
89
    void next(bool* b);
90
    void next(SkRegion* region);
91
92
6.67k
    bool nextBool() {
93
6.67k
        bool b;
94
6.67k
        this->next(&b);
95
6.67k
        return b;
96
6.67k
    }
97
98
    void nextRange(float* f, float min, float max);
99
100
private:
101
    template <typename T>
102
    T nextT();
103
104
    const uint8_t *fData;
105
    size_t fSize;
106
    size_t fNextByte;
107
    friend void fuzz__MakeEncoderCorpus(Fuzz*);
108
109
    void nextBytes(void* ptr, size_t size);
110
};
111
112
template <typename Arg, typename... Args>
113
1.34M
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.34M
   this->next(first);
115
1.34M
   this->next(rest...);
116
1.34M
}
void Fuzz::next<bool, bool*, SkPoint*, float*>(bool*, bool*, SkPoint*, float*)
Line
Count
Source
113
599
inline void Fuzz::next(Arg* first, Args... rest) {
114
599
   this->next(first);
115
599
   this->next(rest...);
116
599
}
void Fuzz::next<bool, SkPoint*, float*>(bool*, SkPoint*, float*)
Line
Count
Source
113
599
inline void Fuzz::next(Arg* first, Args... rest) {
114
599
   this->next(first);
115
599
   this->next(rest...);
116
599
}
void Fuzz::next<SkPoint, float*>(SkPoint*, float*)
Line
Count
Source
113
599
inline void Fuzz::next(Arg* first, Args... rest) {
114
599
   this->next(first);
115
599
   this->next(rest...);
116
599
}
void Fuzz::next<bool, bool*, float*, float*, SkPoint*, SkPoint*>(bool*, bool*, float*, float*, SkPoint*, SkPoint*)
Line
Count
Source
113
1.72k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.72k
   this->next(first);
115
1.72k
   this->next(rest...);
116
1.72k
}
void Fuzz::next<bool, float*, float*, SkPoint*, SkPoint*>(bool*, float*, float*, SkPoint*, SkPoint*)
Line
Count
Source
113
1.72k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.72k
   this->next(first);
115
1.72k
   this->next(rest...);
116
1.72k
}
void Fuzz::next<float, float*, SkPoint*, SkPoint*>(float*, float*, SkPoint*, SkPoint*)
Line
Count
Source
113
1.72k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.72k
   this->next(first);
115
1.72k
   this->next(rest...);
116
1.72k
}
void Fuzz::next<float, SkPoint*, SkPoint*>(float*, SkPoint*, SkPoint*)
Line
Count
Source
113
1.72k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.72k
   this->next(first);
115
1.72k
   this->next(rest...);
116
1.72k
}
void Fuzz::next<float, float*, bool*, bool*>(float*, float*, bool*, bool*)
Line
Count
Source
113
54.4k
inline void Fuzz::next(Arg* first, Args... rest) {
114
54.4k
   this->next(first);
115
54.4k
   this->next(rest...);
116
54.4k
}
void Fuzz::next<float, bool*, bool*>(float*, bool*, bool*)
Line
Count
Source
113
54.5k
inline void Fuzz::next(Arg* first, Args... rest) {
114
54.5k
   this->next(first);
115
54.5k
   this->next(rest...);
116
54.5k
}
void Fuzz::next<float, float*, float*, bool*, bool*>(float*, float*, float*, bool*, bool*)
Line
Count
Source
113
48.5k
inline void Fuzz::next(Arg* first, Args... rest) {
114
48.5k
   this->next(first);
115
48.5k
   this->next(rest...);
116
48.5k
}
void Fuzz::next<float, float*, unsigned int*>(float*, float*, unsigned int*)
Line
Count
Source
113
25.0k
inline void Fuzz::next(Arg* first, Args... rest) {
114
25.0k
   this->next(first);
115
25.0k
   this->next(rest...);
116
25.0k
}
void Fuzz::next<float, unsigned int*>(float*, unsigned int*)
Line
Count
Source
113
25.0k
inline void Fuzz::next(Arg* first, Args... rest) {
114
25.0k
   this->next(first);
115
25.0k
   this->next(rest...);
116
25.0k
}
void Fuzz::next<unsigned int, unsigned int*>(unsigned int*, unsigned int*)
Line
Count
Source
113
593
inline void Fuzz::next(Arg* first, Args... rest) {
114
593
   this->next(first);
115
593
   this->next(rest...);
116
593
}
void Fuzz::next<SkRect, unsigned char*>(SkRect*, unsigned char*)
Line
Count
Source
113
888
inline void Fuzz::next(Arg* first, Args... rest) {
114
888
   this->next(first);
115
888
   this->next(rest...);
116
888
}
void Fuzz::next<float, float*>(float*, float*)
Line
Count
Source
113
401k
inline void Fuzz::next(Arg* first, Args... rest) {
114
401k
   this->next(first);
115
401k
   this->next(rest...);
116
401k
}
void Fuzz::next<float, float*, float*>(float*, float*, float*)
Line
Count
Source
113
123k
inline void Fuzz::next(Arg* first, Args... rest) {
114
123k
   this->next(first);
115
123k
   this->next(rest...);
116
123k
}
void Fuzz::next<SkRect, bool*>(SkRect*, bool*)
Line
Count
Source
113
3.68k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.68k
   this->next(first);
115
3.68k
   this->next(rest...);
116
3.68k
}
void Fuzz::next<SkRect, float*, float*, bool*>(SkRect*, float*, float*, bool*)
Line
Count
Source
113
3.00k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.00k
   this->next(first);
115
3.00k
   this->next(rest...);
116
3.00k
}
void Fuzz::next<float, float*, bool*>(float*, float*, bool*)
Line
Count
Source
113
24.7k
inline void Fuzz::next(Arg* first, Args... rest) {
114
24.7k
   this->next(first);
115
24.7k
   this->next(rest...);
116
24.7k
}
void Fuzz::next<float, bool*>(float*, bool*)
Line
Count
Source
113
34.7k
inline void Fuzz::next(Arg* first, Args... rest) {
114
34.7k
   this->next(first);
115
34.7k
   this->next(rest...);
116
34.7k
}
void Fuzz::next<SkIRect, SkRect*, bool*>(SkIRect*, SkRect*, bool*)
Line
Count
Source
113
417
inline void Fuzz::next(Arg* first, Args... rest) {
114
417
   this->next(first);
115
417
   this->next(rest...);
116
417
}
void Fuzz::next<bool, SkRect*>(bool*, SkRect*)
Line
Count
Source
113
630
inline void Fuzz::next(Arg* first, Args... rest) {
114
630
   this->next(first);
115
630
   this->next(rest...);
116
630
}
void Fuzz::next<bool, bool*>(bool*, bool*)
Line
Count
Source
113
88.5k
inline void Fuzz::next(Arg* first, Args... rest) {
114
88.5k
   this->next(first);
115
88.5k
   this->next(rest...);
116
88.5k
}
void Fuzz::next<SkPoint, SkPoint*>(SkPoint*, SkPoint*)
Line
Count
Source
113
2.82k
inline void Fuzz::next(Arg* first, Args... rest) {
114
2.82k
   this->next(first);
115
2.82k
   this->next(rest...);
116
2.82k
}
void Fuzz::next<float, SkPoint*>(float*, SkPoint*)
Line
Count
Source
113
715
inline void Fuzz::next(Arg* first, Args... rest) {
114
715
   this->next(first);
115
715
   this->next(rest...);
116
715
}
void Fuzz::next<SkRect, float*, float*>(SkRect*, float*, float*)
Line
Count
Source
113
866
inline void Fuzz::next(Arg* first, Args... rest) {
114
866
   this->next(first);
115
866
   this->next(rest...);
116
866
}
void Fuzz::next<float, float*, float*, float*, bool*, bool*>(float*, float*, float*, float*, bool*, bool*)
Line
Count
Source
113
3.30k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.30k
   this->next(first);
115
3.30k
   this->next(rest...);
116
3.30k
}
void Fuzz::next<float, float*, float*, float*, unsigned int*, bool*, bool*>(float*, float*, float*, float*, unsigned int*, bool*, bool*)
Line
Count
Source
113
14.1k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.1k
   this->next(first);
115
14.1k
   this->next(rest...);
116
14.1k
}
void Fuzz::next<float, float*, float*, unsigned int*, bool*, bool*>(float*, float*, float*, unsigned int*, bool*, bool*)
Line
Count
Source
113
14.1k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.1k
   this->next(first);
115
14.1k
   this->next(rest...);
116
14.1k
}
void Fuzz::next<float, float*, unsigned int*, bool*, bool*>(float*, float*, unsigned int*, bool*, bool*)
Line
Count
Source
113
14.1k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.1k
   this->next(first);
115
14.1k
   this->next(rest...);
116
14.1k
}
void Fuzz::next<float, unsigned int*, bool*, bool*>(float*, unsigned int*, bool*, bool*)
Line
Count
Source
113
14.1k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.1k
   this->next(first);
115
14.1k
   this->next(rest...);
116
14.1k
}
void Fuzz::next<unsigned int, bool*, bool*>(unsigned int*, bool*, bool*)
Line
Count
Source
113
14.1k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.1k
   this->next(first);
115
14.1k
   this->next(rest...);
116
14.1k
}
void Fuzz::next<SkRect, SkRect*>(SkRect*, SkRect*)
Line
Count
Source
113
1.30k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.30k
   this->next(first);
115
1.30k
   this->next(rest...);
116
1.30k
}
void Fuzz::next<SkPoint3, unsigned int*, float*, float*>(SkPoint3*, unsigned int*, float*, float*)
Line
Count
Source
113
483
inline void Fuzz::next(Arg* first, Args... rest) {
114
483
   this->next(first);
115
483
   this->next(rest...);
116
483
}
void Fuzz::next<unsigned int, float*, float*>(unsigned int*, float*, float*)
Line
Count
Source
113
594
inline void Fuzz::next(Arg* first, Args... rest) {
114
594
   this->next(first);
115
594
   this->next(rest...);
116
594
}
void Fuzz::next<SkPoint3, SkPoint3*, float*, float*, unsigned int*, float*, float*>(SkPoint3*, SkPoint3*, float*, float*, unsigned int*, float*, float*)
Line
Count
Source
113
111
inline void Fuzz::next(Arg* first, Args... rest) {
114
111
   this->next(first);
115
111
   this->next(rest...);
116
111
}
void Fuzz::next<SkPoint3, float*, float*, unsigned int*, float*, float*>(SkPoint3*, float*, float*, unsigned int*, float*, float*)
Line
Count
Source
113
111
inline void Fuzz::next(Arg* first, Args... rest) {
114
111
   this->next(first);
115
111
   this->next(rest...);
116
111
}
void Fuzz::next<float, float*, unsigned int*, float*, float*>(float*, float*, unsigned int*, float*, float*)
Line
Count
Source
113
111
inline void Fuzz::next(Arg* first, Args... rest) {
114
111
   this->next(first);
115
111
   this->next(rest...);
116
111
}
void Fuzz::next<float, unsigned int*, float*, float*>(float*, unsigned int*, float*, float*)
Line
Count
Source
113
111
inline void Fuzz::next(Arg* first, Args... rest) {
114
111
   this->next(first);
115
111
   this->next(rest...);
116
111
}
void Fuzz::next<SkPoint3, unsigned int*, float*, float*, float*>(SkPoint3*, unsigned int*, float*, float*, float*)
Line
Count
Source
113
875
inline void Fuzz::next(Arg* first, Args... rest) {
114
875
   this->next(first);
115
875
   this->next(rest...);
116
875
}
void Fuzz::next<unsigned int, float*, float*, float*>(unsigned int*, float*, float*, float*)
Line
Count
Source
113
4.02k
inline void Fuzz::next(Arg* first, Args... rest) {
114
4.02k
   this->next(first);
115
4.02k
   this->next(rest...);
116
4.02k
}
void Fuzz::next<SkPoint3, SkPoint3*, float*, float*, unsigned int*, float*, float*, float*>(SkPoint3*, SkPoint3*, float*, float*, unsigned int*, float*, float*, float*)
Line
Count
Source
113
3.15k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.15k
   this->next(first);
115
3.15k
   this->next(rest...);
116
3.15k
}
void Fuzz::next<SkPoint3, float*, float*, unsigned int*, float*, float*, float*>(SkPoint3*, float*, float*, unsigned int*, float*, float*, float*)
Line
Count
Source
113
3.15k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.15k
   this->next(first);
115
3.15k
   this->next(rest...);
116
3.15k
}
void Fuzz::next<float, float*, unsigned int*, float*, float*, float*>(float*, float*, unsigned int*, float*, float*, float*)
Line
Count
Source
113
3.15k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.15k
   this->next(first);
115
3.15k
   this->next(rest...);
116
3.15k
}
void Fuzz::next<float, unsigned int*, float*, float*, float*>(float*, unsigned int*, float*, float*, float*)
Line
Count
Source
113
3.15k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.15k
   this->next(first);
115
3.15k
   this->next(rest...);
116
3.15k
}
void Fuzz::next<int, int*>(int*, int*)
Line
Count
Source
113
10.6k
inline void Fuzz::next(Arg* first, Args... rest) {
114
10.6k
   this->next(first);
115
10.6k
   this->next(rest...);
116
10.6k
}
void Fuzz::next<float, float*, float*, float*>(float*, float*, float*, float*)
Line
Count
Source
113
117k
inline void Fuzz::next(Arg* first, Args... rest) {
114
117k
   this->next(first);
115
117k
   this->next(rest...);
116
117k
}
void Fuzz::next<float, float*, float*, float*, float*>(float*, float*, float*, float*, float*)
Line
Count
Source
113
61.1k
inline void Fuzz::next(Arg* first, Args... rest) {
114
61.1k
   this->next(first);
115
61.1k
   this->next(rest...);
116
61.1k
}
void Fuzz::next<float, float*, float*, float*, float*, float*>(float*, float*, float*, float*, float*, float*)
Line
Count
Source
113
27.2k
inline void Fuzz::next(Arg* first, Args... rest) {
114
27.2k
   this->next(first);
115
27.2k
   this->next(rest...);
116
27.2k
}
Unexecuted instantiation: void Fuzz::next<unsigned char, unsigned char*>(unsigned char*, unsigned char*)
void Fuzz::next<unsigned int, float*>(unsigned int*, float*)
Line
Count
Source
113
132k
inline void Fuzz::next(Arg* first, Args... rest) {
114
132k
   this->next(first);
115
132k
   this->next(rest...);
116
132k
}
117
118
template <typename T, typename Min, typename Max>
119
4.79M
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
4.79M
    using Raw = typename sk_strip_enum<T>::type;
122
4.79M
    Raw raw;
123
4.79M
    this->next(&raw);
124
125
4.79M
    if (raw < (Raw)min) { raw = (Raw)min; }
126
4.79M
    if (raw > (Raw)max) { raw = (Raw)max; }
127
4.79M
    *value = (T)raw;
128
4.79M
}
void Fuzz::nextRange<unsigned int, int, int>(unsigned int*, int, int)
Line
Count
Source
119
437k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
437k
    using Raw = typename sk_strip_enum<T>::type;
122
437k
    Raw raw;
123
437k
    this->next(&raw);
124
125
437k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
437k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
437k
    *value = (T)raw;
128
437k
}
void Fuzz::nextRange<int, int, int>(int*, int, int)
Line
Count
Source
119
1.22M
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
1.22M
    using Raw = typename sk_strip_enum<T>::type;
122
1.22M
    Raw raw;
123
1.22M
    this->next(&raw);
124
125
1.22M
    if (raw < (Raw)min) { raw = (Raw)min; }
126
1.22M
    if (raw > (Raw)max) { raw = (Raw)max; }
127
1.22M
    *value = (T)raw;
128
1.22M
}
void Fuzz::nextRange<SkCanvas::PointMode, SkCanvas::PointMode, SkCanvas::PointMode>(SkCanvas::PointMode*, SkCanvas::PointMode, SkCanvas::PointMode)
Line
Count
Source
119
3.90k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
3.90k
    using Raw = typename sk_strip_enum<T>::type;
122
3.90k
    Raw raw;
123
3.90k
    this->next(&raw);
124
125
3.90k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
3.90k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
3.90k
    *value = (T)raw;
128
3.90k
}
void Fuzz::nextRange<unsigned long, int, int>(unsigned long*, int, int)
Line
Count
Source
119
3.90k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
3.90k
    using Raw = typename sk_strip_enum<T>::type;
122
3.90k
    Raw raw;
123
3.90k
    this->next(&raw);
124
125
3.90k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
3.90k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
3.90k
    *value = (T)raw;
128
3.90k
}
void Fuzz::nextRange<signed char, signed char, signed char>(signed char*, signed char, signed char)
Line
Count
Source
119
3.73k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
3.73k
    using Raw = typename sk_strip_enum<T>::type;
122
3.73k
    Raw raw;
123
3.73k
    this->next(&raw);
124
125
3.73k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
3.73k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
3.73k
    *value = (T)raw;
128
3.73k
}
void Fuzz::nextRange<unsigned char, unsigned char, unsigned char>(unsigned char*, unsigned char, unsigned char)
Line
Count
Source
119
23.1k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
23.1k
    using Raw = typename sk_strip_enum<T>::type;
122
23.1k
    Raw raw;
123
23.1k
    this->next(&raw);
124
125
23.1k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
23.1k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
23.1k
    *value = (T)raw;
128
23.1k
}
void Fuzz::nextRange<SkVertices::VertexMode, int, SkVertices::VertexMode>(SkVertices::VertexMode*, int, SkVertices::VertexMode)
Line
Count
Source
119
1.14k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
1.14k
    using Raw = typename sk_strip_enum<T>::type;
122
1.14k
    Raw raw;
123
1.14k
    this->next(&raw);
124
125
1.14k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
1.14k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
1.14k
    *value = (T)raw;
128
1.14k
}
void Fuzz::nextRange<SkBlendMode, int, SkBlendMode>(SkBlendMode*, int, SkBlendMode)
Line
Count
Source
119
4.75k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
4.75k
    using Raw = typename sk_strip_enum<T>::type;
122
4.75k
    Raw raw;
123
4.75k
    this->next(&raw);
124
125
4.75k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
4.75k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
4.75k
    *value = (T)raw;
128
4.75k
}
void Fuzz::nextRange<unsigned short, int, int>(unsigned short*, int, int)
Line
Count
Source
119
11.1k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
11.1k
    using Raw = typename sk_strip_enum<T>::type;
122
11.1k
    Raw raw;
123
11.1k
    this->next(&raw);
124
125
11.1k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
11.1k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
11.1k
    *value = (T)raw;
128
11.1k
}
void Fuzz::nextRange<float, int, int>(float*, int, int)
Line
Count
Source
119
3.34k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
3.34k
    using Raw = typename sk_strip_enum<T>::type;
122
3.34k
    Raw raw;
123
3.34k
    this->next(&raw);
124
125
3.34k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
3.34k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
3.34k
    *value = (T)raw;
128
3.34k
}
void Fuzz::nextRange<unsigned char, int, int>(unsigned char*, int, int)
Line
Count
Source
119
645k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
645k
    using Raw = typename sk_strip_enum<T>::type;
122
645k
    Raw raw;
123
645k
    this->next(&raw);
124
125
645k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
645k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
645k
    *value = (T)raw;
128
645k
}
void Fuzz::nextRange<unsigned char, int, unsigned char>(unsigned char*, int, unsigned char)
Line
Count
Source
119
2.37M
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
2.37M
    using Raw = typename sk_strip_enum<T>::type;
122
2.37M
    Raw raw;
123
2.37M
    this->next(&raw);
124
125
2.37M
    if (raw < (Raw)min) { raw = (Raw)min; }
126
2.37M
    if (raw > (Raw)max) { raw = (Raw)max; }
127
2.37M
    *value = (T)raw;
128
2.37M
}
void Fuzz::nextRange<char, int, int>(char*, int, int)
Line
Count
Source
119
8.81k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
8.81k
    using Raw = typename sk_strip_enum<T>::type;
122
8.81k
    Raw raw;
123
8.81k
    this->next(&raw);
124
125
8.81k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
8.81k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
8.81k
    *value = (T)raw;
128
8.81k
}
void Fuzz::nextRange<SkPathFillType, int, int>(SkPathFillType*, int, int)
Line
Count
Source
119
18.3k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
18.3k
    using Raw = typename sk_strip_enum<T>::type;
122
18.3k
    Raw raw;
123
18.3k
    this->next(&raw);
124
125
18.3k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
18.3k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
18.3k
    *value = (T)raw;
128
18.3k
}
void Fuzz::nextRange<SkPathOp, int, SkPathOp>(SkPathOp*, int, SkPathOp)
Line
Count
Source
119
20.2k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
20.2k
    using Raw = typename sk_strip_enum<T>::type;
122
20.2k
    Raw raw;
123
20.2k
    this->next(&raw);
124
125
20.2k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
20.2k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
20.2k
    *value = (T)raw;
128
20.2k
}
void Fuzz::nextRange<SkPathFillType, int, SkPathFillType>(SkPathFillType*, int, SkPathFillType)
Line
Count
Source
119
9.48k
inline void Fuzz::nextRange(T* value, Min min, Max max) {
120
    // UBSAN worries if we make an enum with out of range values, even temporarily.
121
9.48k
    using Raw = typename sk_strip_enum<T>::type;
122
9.48k
    Raw raw;
123
9.48k
    this->next(&raw);
124
125
9.48k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
9.48k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
9.48k
    *value = (T)raw;
128
9.48k
}
129
130
template <typename T>
131
488k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
488k
    using U = typename std::underlying_type<T>::type;
136
488k
    U v;
137
488k
    this->next(&v);
138
488k
    if (v < (U)0) { *value = (T)0; return;}
139
449k
    if (v > (U)max) { *value = (T)max; return;}
140
233k
    *value = (T)v;
141
233k
}
void Fuzz::nextEnum<SkPaint::Style>(SkPaint::Style*, SkPaint::Style)
Line
Count
Source
131
66.1k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
66.1k
    using U = typename std::underlying_type<T>::type;
136
66.1k
    U v;
137
66.1k
    this->next(&v);
138
66.1k
    if (v < (U)0) { *value = (T)0; return;}
139
66.1k
    if (v > (U)max) { *value = (T)max; return;}
140
31.6k
    *value = (T)v;
141
31.6k
}
void Fuzz::nextEnum<SkTileMode>(SkTileMode*, SkTileMode)
Line
Count
Source
131
12.5k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
12.5k
    using U = typename std::underlying_type<T>::type;
136
12.5k
    U v;
137
12.5k
    this->next(&v);
138
12.5k
    if (v < (U)0) { *value = (T)0; return;}
139
9.84k
    if (v > (U)max) { *value = (T)max; return;}
140
4.93k
    *value = (T)v;
141
4.93k
}
void Fuzz::nextEnum<SkPath1DPathEffect::Style>(SkPath1DPathEffect::Style*, SkPath1DPathEffect::Style)
Line
Count
Source
131
2.93k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
2.93k
    using U = typename std::underlying_type<T>::type;
136
2.93k
    U v;
137
2.93k
    this->next(&v);
138
2.93k
    if (v < (U)0) { *value = (T)0; return;}
139
2.93k
    if (v > (U)max) { *value = (T)max; return;}
140
460
    *value = (T)v;
141
460
}
void Fuzz::nextEnum<SkBlurStyle>(SkBlurStyle*, SkBlurStyle)
Line
Count
Source
131
34.6k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
34.6k
    using U = typename std::underlying_type<T>::type;
136
34.6k
    U v;
137
34.6k
    this->next(&v);
138
34.6k
    if (v < (U)0) { *value = (T)0; return;}
139
30.4k
    if (v > (U)max) { *value = (T)max; return;}
140
4.47k
    *value = (T)v;
141
4.47k
}
void Fuzz::nextEnum<SkPaint::Cap>(SkPaint::Cap*, SkPaint::Cap)
Line
Count
Source
131
40.4k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
40.4k
    using U = typename std::underlying_type<T>::type;
136
40.4k
    U v;
137
40.4k
    this->next(&v);
138
40.4k
    if (v < (U)0) { *value = (T)0; return;}
139
40.4k
    if (v > (U)max) { *value = (T)max; return;}
140
20.3k
    *value = (T)v;
141
20.3k
}
void Fuzz::nextEnum<SkPaint::Join>(SkPaint::Join*, SkPaint::Join)
Line
Count
Source
131
40.4k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
40.4k
    using U = typename std::underlying_type<T>::type;
136
40.4k
    U v;
137
40.4k
    this->next(&v);
138
40.4k
    if (v < (U)0) { *value = (T)0; return;}
139
40.4k
    if (v > (U)max) { *value = (T)max; return;}
140
25.4k
    *value = (T)v;
141
25.4k
}
void Fuzz::nextEnum<SkFontHinting>(SkFontHinting*, SkFontHinting)
Line
Count
Source
131
7.53k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
7.53k
    using U = typename std::underlying_type<T>::type;
136
7.53k
    U v;
137
7.53k
    this->next(&v);
138
7.53k
    if (v < (U)0) { *value = (T)0; return;}
139
6.41k
    if (v > (U)max) { *value = (T)max; return;}
140
2.77k
    *value = (T)v;
141
2.77k
}
void Fuzz::nextEnum<SkFont::Edging>(SkFont::Edging*, SkFont::Edging)
Line
Count
Source
131
7.53k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
7.53k
    using U = typename std::underlying_type<T>::type;
136
7.53k
    U v;
137
7.53k
    this->next(&v);
138
7.53k
    if (v < (U)0) { *value = (T)0; return;}
139
6.33k
    if (v > (U)max) { *value = (T)max; return;}
140
2.83k
    *value = (T)v;
141
2.83k
}
void Fuzz::nextEnum<SkTextEncoding>(SkTextEncoding*, SkTextEncoding)
Line
Count
Source
131
28.1k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
28.1k
    using U = typename std::underlying_type<T>::type;
136
28.1k
    U v;
137
28.1k
    this->next(&v);
138
28.1k
    if (v < (U)0) { *value = (T)0; return;}
139
22.8k
    if (v > (U)max) { *value = (T)max; return;}
140
10.1k
    *value = (T)v;
141
10.1k
}
void Fuzz::nextEnum<SkBlendMode>(SkBlendMode*, SkBlendMode)
Line
Count
Source
131
130k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
130k
    using U = typename std::underlying_type<T>::type;
136
130k
    U v;
137
130k
    this->next(&v);
138
130k
    if (v < (U)0) { *value = (T)0; return;}
139
109k
    if (v > (U)max) { *value = (T)max; return;}
140
50.5k
    *value = (T)v;
141
50.5k
}
void Fuzz::nextEnum<SkFilterMode>(SkFilterMode*, SkFilterMode)
Line
Count
Source
131
4.46k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
4.46k
    using U = typename std::underlying_type<T>::type;
136
4.46k
    U v;
137
4.46k
    this->next(&v);
138
4.46k
    if (v < (U)0) { *value = (T)0; return;}
139
3.82k
    if (v > (U)max) { *value = (T)max; return;}
140
879
    *value = (T)v;
141
879
}
void Fuzz::nextEnum<SkMipmapMode>(SkMipmapMode*, SkMipmapMode)
Line
Count
Source
131
4.46k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
4.46k
    using U = typename std::underlying_type<T>::type;
136
4.46k
    U v;
137
4.46k
    this->next(&v);
138
4.46k
    if (v < (U)0) { *value = (T)0; return;}
139
4.04k
    if (v > (U)max) { *value = (T)max; return;}
140
946
    *value = (T)v;
141
946
}
void Fuzz::nextEnum<SkColorChannel>(SkColorChannel*, SkColorChannel)
Line
Count
Source
131
20.0k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
20.0k
    using U = typename std::underlying_type<T>::type;
136
20.0k
    U v;
137
20.0k
    this->next(&v);
138
20.0k
    if (v < (U)0) { *value = (T)0; return;}
139
17.0k
    if (v > (U)max) { *value = (T)max; return;}
140
999
    *value = (T)v;
141
999
}
void Fuzz::nextEnum<SkRegion::Op>(SkRegion::Op*, SkRegion::Op)
Line
Count
Source
131
89.0k
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
89.0k
    using U = typename std::underlying_type<T>::type;
136
89.0k
    U v;
137
89.0k
    this->next(&v);
138
89.0k
    if (v < (U)0) { *value = (T)0; return;}
139
89.0k
    if (v > (U)max) { *value = (T)max; return;}
140
77.2k
    *value = (T)v;
141
77.2k
}
Unexecuted instantiation: void Fuzz::nextEnum<skia::textlayout::TextDirection>(skia::textlayout::TextDirection*, skia::textlayout::TextDirection)
Unexecuted instantiation: void Fuzz::nextEnum<skia::textlayout::TextAlign>(skia::textlayout::TextAlign*, skia::textlayout::TextAlign)
Unexecuted instantiation: void Fuzz::nextEnum<SkAlphaType>(SkAlphaType*, SkAlphaType)
Unexecuted instantiation: void Fuzz::nextEnum<skgpu::Protected>(skgpu::Protected*, skgpu::Protected)
Unexecuted instantiation: void Fuzz::nextEnum<SkPixelGeometry>(SkPixelGeometry*, SkPixelGeometry)
Unexecuted instantiation: void Fuzz::nextEnum<skgpu::Budgeted>(skgpu::Budgeted*, skgpu::Budgeted)
void Fuzz::nextEnum<SkColorType>(SkColorType*, SkColorType)
Line
Count
Source
131
160
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
160
    using U = typename std::underlying_type<T>::type;
136
160
    U v;
137
160
    this->next(&v);
138
160
    if (v < (U)0) { *value = (T)0; return;}
139
81
    if (v > (U)max) { *value = (T)max; return;}
140
11
    *value = (T)v;
141
11
}
void Fuzz::nextEnum<GrSurfaceOrigin>(GrSurfaceOrigin*, GrSurfaceOrigin)
Line
Count
Source
131
160
inline void Fuzz::nextEnum(T* value, T max) {
132
    // This works around the fact that UBSAN will assert if we put an invalid
133
    // value into an enum. We might see issues with enums being represented
134
    // on Windows differently than Linux, but that's not a thing we can fix here.
135
160
    using U = typename std::underlying_type<T>::type;
136
160
    U v;
137
160
    this->next(&v);
138
160
    if (v < (U)0) { *value = (T)0; return;}
139
112
    if (v > (U)max) { *value = (T)max; return;}
140
74
    *value = (T)v;
141
74
}
142
143
template <typename T>
144
197k
inline void Fuzz::nextN(T* ptr, int n) {
145
62.2M
   for (int i = 0; i < n; i++) {
146
62.0M
       this->next(ptr+i);
147
62.0M
   }
148
197k
}
void Fuzz::nextN<float>(float*, int)
Line
Count
Source
144
37.3k
inline void Fuzz::nextN(T* ptr, int n) {
145
574k
   for (int i = 0; i < n; i++) {
146
537k
       this->next(ptr+i);
147
537k
   }
148
37.3k
}
void Fuzz::nextN<unsigned char>(unsigned char*, int)
Line
Count
Source
144
23.2k
inline void Fuzz::nextN(T* ptr, int n) {
145
5.98M
   for (int i = 0; i < n; i++) {
146
5.95M
       this->next(ptr+i);
147
5.95M
   }
148
23.2k
}
void Fuzz::nextN<SkPoint>(SkPoint*, int)
Line
Count
Source
144
68.3k
inline void Fuzz::nextN(T* ptr, int n) {
145
862k
   for (int i = 0; i < n; i++) {
146
794k
       this->next(ptr+i);
147
794k
   }
148
68.3k
}
void Fuzz::nextN<int>(int*, int)
Line
Count
Source
144
1.26k
inline void Fuzz::nextN(T* ptr, int n) {
145
5.56k
   for (int i = 0; i < n; i++) {
146
4.30k
       this->next(ptr+i);
147
4.30k
   }
148
1.26k
}
void Fuzz::nextN<unsigned int>(unsigned int*, int)
Line
Count
Source
144
67.2k
inline void Fuzz::nextN(T* ptr, int n) {
145
54.8M
   for (int i = 0; i < n; i++) {
146
54.7M
       this->next(ptr+i);
147
54.7M
   }
148
67.2k
}
Unexecuted instantiation: void Fuzz::nextN<char>(char*, int)
Unexecuted instantiation: void Fuzz::nextN<char16_t>(char16_t*, int)
149
150
struct Fuzzable {
151
    const char* name;
152
    void (*fn)(Fuzz*);
153
};
154
155
// Not static so that we can link these into oss-fuzz harnesses if we like.
156
#define DEF_FUZZ(name, f)                                               \
157
    void fuzz_##name(Fuzz*);                                            \
158
    sk_tools::Registry<Fuzzable> register_##name({#name, fuzz_##name}); \
159
    void fuzz_##name(Fuzz* f)
160
161
#endif  // Fuzz_DEFINED