Coverage Report

Created: 2024-05-20 07:14

/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
96.8k
    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
914k
    bool exhausted() const {
40
914k
        return fSize == fNextByte;
41
914k
    }
42
43
0
    void deplete() {
44
0
        fNextByte = fSize;
45
0
    }
46
47
13.8k
    size_t remainingSize() const {
48
13.8k
        return fSize - fNextByte;
49
13.8k
    }
50
51
13.8k
    const uint8_t *remainingData() const {
52
13.8k
        return fData + fNextByte;
53
13.8k
    }
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
315M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<unsigned char>(unsigned char*)
Line
Count
Source
64
11.5M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<float>(float*)
Line
Count
Source
64
6.32M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<unsigned int>(unsigned int*)
Line
Count
Source
64
295M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<int>(int*)
Line
Count
Source
64
1.66M
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkRect>(SkRect*)
Line
Count
Source
64
17.2k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkPoint>(SkPoint*)
Line
Count
Source
64
828k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkISize>(SkISize*)
Line
Count
Source
64
15.7k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<unsigned long>(unsigned long*)
Line
Count
Source
64
4.40k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkIRect>(SkIRect*)
Line
Count
Source
64
50.0k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<signed char>(signed char*)
Line
Count
Source
64
4.25k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<unsigned short>(unsigned short*)
Line
Count
Source
64
96.1k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<char>(char*)
Line
Count
Source
64
75.3k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<SkPoint3>(SkPoint3*)
Line
Count
Source
64
10.3k
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
void Fuzz::next<double>(double*)
Line
Count
Source
64
464
    void next(T* t) { this->nextBytes(t, sizeof(T)); }
Unexecuted instantiation: void Fuzz::next<char16_t>(char16_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
0
        // 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
8.17k
    bool nextBool() {
93
8.17k
        bool b;
94
8.17k
        this->next(&b);
95
8.17k
        return b;
96
8.17k
    }
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.36M
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.36M
   this->next(first);
115
1.36M
   this->next(rest...);
116
1.36M
}
void Fuzz::next<float, float*>(float*, float*)
Line
Count
Source
113
416k
inline void Fuzz::next(Arg* first, Args... rest) {
114
416k
   this->next(first);
115
416k
   this->next(rest...);
116
416k
}
void Fuzz::next<float, float*, float*, float*>(float*, float*, float*, float*)
Line
Count
Source
113
124k
inline void Fuzz::next(Arg* first, Args... rest) {
114
124k
   this->next(first);
115
124k
   this->next(rest...);
116
124k
}
void Fuzz::next<float, float*, float*>(float*, float*, float*)
Line
Count
Source
113
130k
inline void Fuzz::next(Arg* first, Args... rest) {
114
130k
   this->next(first);
115
130k
   this->next(rest...);
116
130k
}
void Fuzz::next<float, float*, float*, float*, float*>(float*, float*, float*, float*, float*)
Line
Count
Source
113
61.6k
inline void Fuzz::next(Arg* first, Args... rest) {
114
61.6k
   this->next(first);
115
61.6k
   this->next(rest...);
116
61.6k
}
void Fuzz::next<float, float*, float*, float*, float*, float*>(float*, float*, float*, float*, float*, float*)
Line
Count
Source
113
28.7k
inline void Fuzz::next(Arg* first, Args... rest) {
114
28.7k
   this->next(first);
115
28.7k
   this->next(rest...);
116
28.7k
}
void Fuzz::next<unsigned int, float*>(unsigned int*, float*)
Line
Count
Source
113
86.8k
inline void Fuzz::next(Arg* first, Args... rest) {
114
86.8k
   this->next(first);
115
86.8k
   this->next(rest...);
116
86.8k
}
void Fuzz::next<bool, bool*>(bool*, bool*)
Line
Count
Source
113
96.9k
inline void Fuzz::next(Arg* first, Args... rest) {
114
96.9k
   this->next(first);
115
96.9k
   this->next(rest...);
116
96.9k
}
void Fuzz::next<float, bool*, bool*>(float*, bool*, bool*)
Line
Count
Source
113
62.4k
inline void Fuzz::next(Arg* first, Args... rest) {
114
62.4k
   this->next(first);
115
62.4k
   this->next(rest...);
116
62.4k
}
void Fuzz::next<float, float*, bool*, bool*>(float*, float*, bool*, bool*)
Line
Count
Source
113
62.3k
inline void Fuzz::next(Arg* first, Args... rest) {
114
62.3k
   this->next(first);
115
62.3k
   this->next(rest...);
116
62.3k
}
void Fuzz::next<bool, bool*, SkPoint*, float*>(bool*, bool*, SkPoint*, float*)
Line
Count
Source
113
544
inline void Fuzz::next(Arg* first, Args... rest) {
114
544
   this->next(first);
115
544
   this->next(rest...);
116
544
}
void Fuzz::next<bool, SkPoint*, float*>(bool*, SkPoint*, float*)
Line
Count
Source
113
544
inline void Fuzz::next(Arg* first, Args... rest) {
114
544
   this->next(first);
115
544
   this->next(rest...);
116
544
}
void Fuzz::next<SkPoint, float*>(SkPoint*, float*)
Line
Count
Source
113
544
inline void Fuzz::next(Arg* first, Args... rest) {
114
544
   this->next(first);
115
544
   this->next(rest...);
116
544
}
void Fuzz::next<bool, bool*, float*, float*, SkPoint*, SkPoint*>(bool*, bool*, float*, float*, SkPoint*, SkPoint*)
Line
Count
Source
113
1.66k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.66k
   this->next(first);
115
1.66k
   this->next(rest...);
116
1.66k
}
void Fuzz::next<bool, float*, float*, SkPoint*, SkPoint*>(bool*, float*, float*, SkPoint*, SkPoint*)
Line
Count
Source
113
1.66k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.66k
   this->next(first);
115
1.66k
   this->next(rest...);
116
1.66k
}
void Fuzz::next<float, float*, SkPoint*, SkPoint*>(float*, float*, SkPoint*, SkPoint*)
Line
Count
Source
113
1.66k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.66k
   this->next(first);
115
1.66k
   this->next(rest...);
116
1.66k
}
void Fuzz::next<float, SkPoint*, SkPoint*>(float*, SkPoint*, SkPoint*)
Line
Count
Source
113
1.66k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.66k
   this->next(first);
115
1.66k
   this->next(rest...);
116
1.66k
}
void Fuzz::next<float, float*, float*, bool*, bool*>(float*, float*, float*, bool*, bool*)
Line
Count
Source
113
55.8k
inline void Fuzz::next(Arg* first, Args... rest) {
114
55.8k
   this->next(first);
115
55.8k
   this->next(rest...);
116
55.8k
}
void Fuzz::next<float, float*, unsigned int*>(float*, float*, unsigned int*)
Line
Count
Source
113
26.8k
inline void Fuzz::next(Arg* first, Args... rest) {
114
26.8k
   this->next(first);
115
26.8k
   this->next(rest...);
116
26.8k
}
void Fuzz::next<float, unsigned int*>(float*, unsigned int*)
Line
Count
Source
113
26.8k
inline void Fuzz::next(Arg* first, Args... rest) {
114
26.8k
   this->next(first);
115
26.8k
   this->next(rest...);
116
26.8k
}
void Fuzz::next<unsigned int, unsigned int*>(unsigned int*, unsigned int*)
Line
Count
Source
113
577
inline void Fuzz::next(Arg* first, Args... rest) {
114
577
   this->next(first);
115
577
   this->next(rest...);
116
577
}
void Fuzz::next<SkRect, unsigned char*>(SkRect*, unsigned char*)
Line
Count
Source
113
876
inline void Fuzz::next(Arg* first, Args... rest) {
114
876
   this->next(first);
115
876
   this->next(rest...);
116
876
}
void Fuzz::next<SkRect, bool*>(SkRect*, bool*)
Line
Count
Source
113
3.80k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.80k
   this->next(first);
115
3.80k
   this->next(rest...);
116
3.80k
}
void Fuzz::next<SkRect, float*, float*, bool*>(SkRect*, float*, float*, bool*)
Line
Count
Source
113
3.20k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.20k
   this->next(first);
115
3.20k
   this->next(rest...);
116
3.20k
}
void Fuzz::next<float, float*, bool*>(float*, float*, bool*)
Line
Count
Source
113
18.7k
inline void Fuzz::next(Arg* first, Args... rest) {
114
18.7k
   this->next(first);
115
18.7k
   this->next(rest...);
116
18.7k
}
void Fuzz::next<float, bool*>(float*, bool*)
Line
Count
Source
113
32.6k
inline void Fuzz::next(Arg* first, Args... rest) {
114
32.6k
   this->next(first);
115
32.6k
   this->next(rest...);
116
32.6k
}
void Fuzz::next<SkIRect, SkRect*, bool*>(SkIRect*, SkRect*, bool*)
Line
Count
Source
113
268
inline void Fuzz::next(Arg* first, Args... rest) {
114
268
   this->next(first);
115
268
   this->next(rest...);
116
268
}
void Fuzz::next<bool, SkRect*>(bool*, SkRect*)
Line
Count
Source
113
886
inline void Fuzz::next(Arg* first, Args... rest) {
114
886
   this->next(first);
115
886
   this->next(rest...);
116
886
}
void Fuzz::next<SkPoint, SkPoint*>(SkPoint*, SkPoint*)
Line
Count
Source
113
3.22k
inline void Fuzz::next(Arg* first, Args... rest) {
114
3.22k
   this->next(first);
115
3.22k
   this->next(rest...);
116
3.22k
}
void Fuzz::next<float, SkPoint*>(float*, SkPoint*)
Line
Count
Source
113
574
inline void Fuzz::next(Arg* first, Args... rest) {
114
574
   this->next(first);
115
574
   this->next(rest...);
116
574
}
void Fuzz::next<SkRect, float*, float*>(SkRect*, float*, float*)
Line
Count
Source
113
932
inline void Fuzz::next(Arg* first, Args... rest) {
114
932
   this->next(first);
115
932
   this->next(rest...);
116
932
}
void Fuzz::next<float, float*, float*, float*, bool*, bool*>(float*, float*, float*, float*, bool*, bool*)
Line
Count
Source
113
4.78k
inline void Fuzz::next(Arg* first, Args... rest) {
114
4.78k
   this->next(first);
115
4.78k
   this->next(rest...);
116
4.78k
}
void Fuzz::next<float, float*, float*, float*, unsigned int*, bool*, bool*>(float*, float*, float*, float*, unsigned int*, bool*, bool*)
Line
Count
Source
113
14.0k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.0k
   this->next(first);
115
14.0k
   this->next(rest...);
116
14.0k
}
void Fuzz::next<float, float*, float*, unsigned int*, bool*, bool*>(float*, float*, float*, unsigned int*, bool*, bool*)
Line
Count
Source
113
14.0k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.0k
   this->next(first);
115
14.0k
   this->next(rest...);
116
14.0k
}
void Fuzz::next<float, float*, unsigned int*, bool*, bool*>(float*, float*, unsigned int*, bool*, bool*)
Line
Count
Source
113
14.0k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.0k
   this->next(first);
115
14.0k
   this->next(rest...);
116
14.0k
}
void Fuzz::next<float, unsigned int*, bool*, bool*>(float*, unsigned int*, bool*, bool*)
Line
Count
Source
113
14.0k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.0k
   this->next(first);
115
14.0k
   this->next(rest...);
116
14.0k
}
void Fuzz::next<unsigned int, bool*, bool*>(unsigned int*, bool*, bool*)
Line
Count
Source
113
14.0k
inline void Fuzz::next(Arg* first, Args... rest) {
114
14.0k
   this->next(first);
115
14.0k
   this->next(rest...);
116
14.0k
}
void Fuzz::next<SkRect, SkRect*>(SkRect*, SkRect*)
Line
Count
Source
113
1.41k
inline void Fuzz::next(Arg* first, Args... rest) {
114
1.41k
   this->next(first);
115
1.41k
   this->next(rest...);
116
1.41k
}
void Fuzz::next<SkPoint3, unsigned int*, float*, float*>(SkPoint3*, unsigned int*, float*, float*)
Line
Count
Source
113
768
inline void Fuzz::next(Arg* first, Args... rest) {
114
768
   this->next(first);
115
768
   this->next(rest...);
116
768
}
void Fuzz::next<unsigned int, float*, float*>(unsigned int*, float*, float*)
Line
Count
Source
113
883
inline void Fuzz::next(Arg* first, Args... rest) {
114
883
   this->next(first);
115
883
   this->next(rest...);
116
883
}
void Fuzz::next<SkPoint3, SkPoint3*, float*, float*, unsigned int*, float*, float*>(SkPoint3*, SkPoint3*, float*, float*, unsigned int*, float*, float*)
Line
Count
Source
113
115
inline void Fuzz::next(Arg* first, Args... rest) {
114
115
   this->next(first);
115
115
   this->next(rest...);
116
115
}
void Fuzz::next<SkPoint3, float*, float*, unsigned int*, float*, float*>(SkPoint3*, float*, float*, unsigned int*, float*, float*)
Line
Count
Source
113
115
inline void Fuzz::next(Arg* first, Args... rest) {
114
115
   this->next(first);
115
115
   this->next(rest...);
116
115
}
void Fuzz::next<float, float*, unsigned int*, float*, float*>(float*, float*, unsigned int*, float*, float*)
Line
Count
Source
113
115
inline void Fuzz::next(Arg* first, Args... rest) {
114
115
   this->next(first);
115
115
   this->next(rest...);
116
115
}
void Fuzz::next<float, unsigned int*, float*, float*>(float*, unsigned int*, float*, float*)
Line
Count
Source
113
115
inline void Fuzz::next(Arg* first, Args... rest) {
114
115
   this->next(first);
115
115
   this->next(rest...);
116
115
}
void Fuzz::next<SkPoint3, unsigned int*, float*, float*, float*>(SkPoint3*, unsigned int*, float*, float*, float*)
Line
Count
Source
113
684
inline void Fuzz::next(Arg* first, Args... rest) {
114
684
   this->next(first);
115
684
   this->next(rest...);
116
684
}
void Fuzz::next<unsigned int, float*, float*, float*>(unsigned int*, float*, float*, float*)
Line
Count
Source
113
5.00k
inline void Fuzz::next(Arg* first, Args... rest) {
114
5.00k
   this->next(first);
115
5.00k
   this->next(rest...);
116
5.00k
}
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
4.31k
inline void Fuzz::next(Arg* first, Args... rest) {
114
4.31k
   this->next(first);
115
4.31k
   this->next(rest...);
116
4.31k
}
void Fuzz::next<SkPoint3, float*, float*, unsigned int*, float*, float*, float*>(SkPoint3*, float*, float*, unsigned int*, float*, float*, float*)
Line
Count
Source
113
4.31k
inline void Fuzz::next(Arg* first, Args... rest) {
114
4.31k
   this->next(first);
115
4.31k
   this->next(rest...);
116
4.31k
}
void Fuzz::next<float, float*, unsigned int*, float*, float*, float*>(float*, float*, unsigned int*, float*, float*, float*)
Line
Count
Source
113
4.31k
inline void Fuzz::next(Arg* first, Args... rest) {
114
4.31k
   this->next(first);
115
4.31k
   this->next(rest...);
116
4.31k
}
void Fuzz::next<float, unsigned int*, float*, float*, float*>(float*, unsigned int*, float*, float*, float*)
Line
Count
Source
113
4.31k
inline void Fuzz::next(Arg* first, Args... rest) {
114
4.31k
   this->next(first);
115
4.31k
   this->next(rest...);
116
4.31k
}
void Fuzz::next<int, int*>(int*, int*)
Line
Count
Source
113
11.2k
inline void Fuzz::next(Arg* first, Args... rest) {
114
11.2k
   this->next(first);
115
11.2k
   this->next(rest...);
116
11.2k
}
Unexecuted instantiation: void Fuzz::next<unsigned char, unsigned char*>(unsigned char*, unsigned char*)
117
118
template <typename T, typename Min, typename Max>
119
5.25M
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
5.25M
    using Raw = typename sk_strip_enum<T>::type;
122
5.25M
    Raw raw;
123
5.25M
    this->next(&raw);
124
125
5.25M
    if (raw < (Raw)min) { raw = (Raw)min; }
126
5.25M
    if (raw > (Raw)max) { raw = (Raw)max; }
127
5.25M
    *value = (T)raw;
128
5.25M
}
void Fuzz::nextRange<unsigned char, int, unsigned char>(unsigned char*, int, unsigned char)
Line
Count
Source
119
2.62M
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.62M
    using Raw = typename sk_strip_enum<T>::type;
122
2.62M
    Raw raw;
123
2.62M
    this->next(&raw);
124
125
2.62M
    if (raw < (Raw)min) { raw = (Raw)min; }
126
2.62M
    if (raw > (Raw)max) { raw = (Raw)max; }
127
2.62M
    *value = (T)raw;
128
2.62M
}
void Fuzz::nextRange<unsigned char, int, int>(unsigned char*, int, int)
Line
Count
Source
119
697k
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
697k
    using Raw = typename sk_strip_enum<T>::type;
122
697k
    Raw raw;
123
697k
    this->next(&raw);
124
125
697k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
697k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
697k
    *value = (T)raw;
128
697k
}
void Fuzz::nextRange<unsigned int, int, int>(unsigned int*, int, int)
Line
Count
Source
119
467k
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
467k
    using Raw = typename sk_strip_enum<T>::type;
122
467k
    Raw raw;
123
467k
    this->next(&raw);
124
125
467k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
467k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
467k
    *value = (T)raw;
128
467k
}
void Fuzz::nextRange<int, int, int>(int*, int, int)
Line
Count
Source
119
1.33M
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.33M
    using Raw = typename sk_strip_enum<T>::type;
122
1.33M
    Raw raw;
123
1.33M
    this->next(&raw);
124
125
1.33M
    if (raw < (Raw)min) { raw = (Raw)min; }
126
1.33M
    if (raw > (Raw)max) { raw = (Raw)max; }
127
1.33M
    *value = (T)raw;
128
1.33M
}
void Fuzz::nextRange<SkCanvas::PointMode, SkCanvas::PointMode, SkCanvas::PointMode>(SkCanvas::PointMode*, SkCanvas::PointMode, SkCanvas::PointMode)
Line
Count
Source
119
4.40k
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.40k
    using Raw = typename sk_strip_enum<T>::type;
122
4.40k
    Raw raw;
123
4.40k
    this->next(&raw);
124
125
4.40k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
4.40k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
4.40k
    *value = (T)raw;
128
4.40k
}
void Fuzz::nextRange<unsigned long, int, int>(unsigned long*, int, int)
Line
Count
Source
119
4.40k
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.40k
    using Raw = typename sk_strip_enum<T>::type;
122
4.40k
    Raw raw;
123
4.40k
    this->next(&raw);
124
125
4.40k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
4.40k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
4.40k
    *value = (T)raw;
128
4.40k
}
void Fuzz::nextRange<signed char, signed char, signed char>(signed char*, signed char, signed char)
Line
Count
Source
119
4.25k
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.25k
    using Raw = typename sk_strip_enum<T>::type;
122
4.25k
    Raw raw;
123
4.25k
    this->next(&raw);
124
125
4.25k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
4.25k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
4.25k
    *value = (T)raw;
128
4.25k
}
void Fuzz::nextRange<unsigned char, unsigned char, unsigned char>(unsigned char*, unsigned char, unsigned char)
Line
Count
Source
119
25.6k
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
25.6k
    using Raw = typename sk_strip_enum<T>::type;
122
25.6k
    Raw raw;
123
25.6k
    this->next(&raw);
124
125
25.6k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
25.6k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
25.6k
    *value = (T)raw;
128
25.6k
}
void Fuzz::nextRange<SkVertices::VertexMode, int, SkVertices::VertexMode>(SkVertices::VertexMode*, int, SkVertices::VertexMode)
Line
Count
Source
119
1.12k
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.12k
    using Raw = typename sk_strip_enum<T>::type;
122
1.12k
    Raw raw;
123
1.12k
    this->next(&raw);
124
125
1.12k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
1.12k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
1.12k
    *value = (T)raw;
128
1.12k
}
void Fuzz::nextRange<SkBlendMode, int, SkBlendMode>(SkBlendMode*, int, SkBlendMode)
Line
Count
Source
119
4.56k
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.56k
    using Raw = typename sk_strip_enum<T>::type;
122
4.56k
    Raw raw;
123
4.56k
    this->next(&raw);
124
125
4.56k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
4.56k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
4.56k
    *value = (T)raw;
128
4.56k
}
void Fuzz::nextRange<unsigned short, int, int>(unsigned short*, int, int)
Line
Count
Source
119
11.6k
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.6k
    using Raw = typename sk_strip_enum<T>::type;
122
11.6k
    Raw raw;
123
11.6k
    this->next(&raw);
124
125
11.6k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
11.6k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
11.6k
    *value = (T)raw;
128
11.6k
}
void Fuzz::nextRange<float, int, int>(float*, int, int)
Line
Count
Source
119
4.55k
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.55k
    using Raw = typename sk_strip_enum<T>::type;
122
4.55k
    Raw raw;
123
4.55k
    this->next(&raw);
124
125
4.55k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
4.55k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
4.55k
    *value = (T)raw;
128
4.55k
}
void Fuzz::nextRange<SkPathFillType, int, int>(SkPathFillType*, int, int)
Line
Count
Source
119
19.4k
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
19.4k
    using Raw = typename sk_strip_enum<T>::type;
122
19.4k
    Raw raw;
123
19.4k
    this->next(&raw);
124
125
19.4k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
19.4k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
19.4k
    *value = (T)raw;
128
19.4k
}
void Fuzz::nextRange<SkPathOp, int, SkPathOp>(SkPathOp*, int, SkPathOp)
Line
Count
Source
119
21.7k
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
21.7k
    using Raw = typename sk_strip_enum<T>::type;
122
21.7k
    Raw raw;
123
21.7k
    this->next(&raw);
124
125
21.7k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
21.7k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
21.7k
    *value = (T)raw;
128
21.7k
}
void Fuzz::nextRange<SkPathFillType, int, SkPathFillType>(SkPathFillType*, int, SkPathFillType)
Line
Count
Source
119
10.4k
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
10.4k
    using Raw = typename sk_strip_enum<T>::type;
122
10.4k
    Raw raw;
123
10.4k
    this->next(&raw);
124
125
10.4k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
10.4k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
10.4k
    *value = (T)raw;
128
10.4k
}
void Fuzz::nextRange<char, int, int>(char*, int, int)
Line
Count
Source
119
8.39k
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.39k
    using Raw = typename sk_strip_enum<T>::type;
122
8.39k
    Raw raw;
123
8.39k
    this->next(&raw);
124
125
8.39k
    if (raw < (Raw)min) { raw = (Raw)min; }
126
8.39k
    if (raw > (Raw)max) { raw = (Raw)max; }
127
8.39k
    *value = (T)raw;
128
8.39k
}
129
130
template <typename T>
131
517k
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
517k
    using U = typename std::underlying_type<T>::type;
136
517k
    U v;
137
517k
    this->next(&v);
138
517k
    if (v < (U)0) { *value = (T)0; return;}
139
474k
    if (v > (U)max) { *value = (T)max; return;}
140
241k
    *value = (T)v;
141
241k
}
void Fuzz::nextEnum<SkRegion::Op>(SkRegion::Op*, SkRegion::Op)
Line
Count
Source
131
93.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
93.4k
    using U = typename std::underlying_type<T>::type;
136
93.4k
    U v;
137
93.4k
    this->next(&v);
138
93.4k
    if (v < (U)0) { *value = (T)0; return;}
139
93.4k
    if (v > (U)max) { *value = (T)max; return;}
140
81.0k
    *value = (T)v;
141
81.0k
}
void Fuzz::nextEnum<SkPaint::Style>(SkPaint::Style*, SkPaint::Style)
Line
Count
Source
131
67.3k
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
67.3k
    using U = typename std::underlying_type<T>::type;
136
67.3k
    U v;
137
67.3k
    this->next(&v);
138
67.3k
    if (v < (U)0) { *value = (T)0; return;}
139
67.3k
    if (v > (U)max) { *value = (T)max; return;}
140
31.4k
    *value = (T)v;
141
31.4k
}
void Fuzz::nextEnum<SkTileMode>(SkTileMode*, SkTileMode)
Line
Count
Source
131
14.2k
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
14.2k
    using U = typename std::underlying_type<T>::type;
136
14.2k
    U v;
137
14.2k
    this->next(&v);
138
14.2k
    if (v < (U)0) { *value = (T)0; return;}
139
11.5k
    if (v > (U)max) { *value = (T)max; return;}
140
6.08k
    *value = (T)v;
141
6.08k
}
void Fuzz::nextEnum<SkPath1DPathEffect::Style>(SkPath1DPathEffect::Style*, SkPath1DPathEffect::Style)
Line
Count
Source
131
2.96k
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.96k
    using U = typename std::underlying_type<T>::type;
136
2.96k
    U v;
137
2.96k
    this->next(&v);
138
2.96k
    if (v < (U)0) { *value = (T)0; return;}
139
2.96k
    if (v > (U)max) { *value = (T)max; return;}
140
477
    *value = (T)v;
141
477
}
void Fuzz::nextEnum<SkBlurStyle>(SkBlurStyle*, SkBlurStyle)
Line
Count
Source
131
33.7k
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
33.7k
    using U = typename std::underlying_type<T>::type;
136
33.7k
    U v;
137
33.7k
    this->next(&v);
138
33.7k
    if (v < (U)0) { *value = (T)0; return;}
139
29.3k
    if (v > (U)max) { *value = (T)max; return;}
140
4.60k
    *value = (T)v;
141
4.60k
}
void Fuzz::nextEnum<SkPaint::Cap>(SkPaint::Cap*, SkPaint::Cap)
Line
Count
Source
131
42.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
42.6k
    using U = typename std::underlying_type<T>::type;
136
42.6k
    U v;
137
42.6k
    this->next(&v);
138
42.6k
    if (v < (U)0) { *value = (T)0; return;}
139
42.6k
    if (v > (U)max) { *value = (T)max; return;}
140
21.2k
    *value = (T)v;
141
21.2k
}
void Fuzz::nextEnum<SkPaint::Join>(SkPaint::Join*, SkPaint::Join)
Line
Count
Source
131
42.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
42.6k
    using U = typename std::underlying_type<T>::type;
136
42.6k
    U v;
137
42.6k
    this->next(&v);
138
42.6k
    if (v < (U)0) { *value = (T)0; return;}
139
42.6k
    if (v > (U)max) { *value = (T)max; return;}
140
26.7k
    *value = (T)v;
141
26.7k
}
void Fuzz::nextEnum<SkFontHinting>(SkFontHinting*, SkFontHinting)
Line
Count
Source
131
8.32k
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
8.32k
    using U = typename std::underlying_type<T>::type;
136
8.32k
    U v;
137
8.32k
    this->next(&v);
138
8.32k
    if (v < (U)0) { *value = (T)0; return;}
139
6.95k
    if (v > (U)max) { *value = (T)max; return;}
140
3.08k
    *value = (T)v;
141
3.08k
}
void Fuzz::nextEnum<SkFont::Edging>(SkFont::Edging*, SkFont::Edging)
Line
Count
Source
131
8.32k
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
8.32k
    using U = typename std::underlying_type<T>::type;
136
8.32k
    U v;
137
8.32k
    this->next(&v);
138
8.32k
    if (v < (U)0) { *value = (T)0; return;}
139
6.88k
    if (v > (U)max) { *value = (T)max; return;}
140
3.04k
    *value = (T)v;
141
3.04k
}
void Fuzz::nextEnum<SkTextEncoding>(SkTextEncoding*, SkTextEncoding)
Line
Count
Source
131
31.3k
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
31.3k
    using U = typename std::underlying_type<T>::type;
136
31.3k
    U v;
137
31.3k
    this->next(&v);
138
31.3k
    if (v < (U)0) { *value = (T)0; return;}
139
25.5k
    if (v > (U)max) { *value = (T)max; return;}
140
11.0k
    *value = (T)v;
141
11.0k
}
void Fuzz::nextEnum<SkBlendMode>(SkBlendMode*, SkBlendMode)
Line
Count
Source
131
132k
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
132k
    using U = typename std::underlying_type<T>::type;
136
132k
    U v;
137
132k
    this->next(&v);
138
132k
    if (v < (U)0) { *value = (T)0; return;}
139
111k
    if (v > (U)max) { *value = (T)max; return;}
140
49.5k
    *value = (T)v;
141
49.5k
}
void Fuzz::nextEnum<SkFilterMode>(SkFilterMode*, SkFilterMode)
Line
Count
Source
131
5.55k
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
5.55k
    using U = typename std::underlying_type<T>::type;
136
5.55k
    U v;
137
5.55k
    this->next(&v);
138
5.55k
    if (v < (U)0) { *value = (T)0; return;}
139
4.76k
    if (v > (U)max) { *value = (T)max; return;}
140
901
    *value = (T)v;
141
901
}
void Fuzz::nextEnum<SkMipmapMode>(SkMipmapMode*, SkMipmapMode)
Line
Count
Source
131
5.55k
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
5.55k
    using U = typename std::underlying_type<T>::type;
136
5.55k
    U v;
137
5.55k
    this->next(&v);
138
5.55k
    if (v < (U)0) { *value = (T)0; return;}
139
5.03k
    if (v > (U)max) { *value = (T)max; return;}
140
872
    *value = (T)v;
141
872
}
void Fuzz::nextEnum<SkColorChannel>(SkColorChannel*, SkColorChannel)
Line
Count
Source
131
27.8k
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
27.8k
    using U = typename std::underlying_type<T>::type;
136
27.8k
    U v;
137
27.8k
    this->next(&v);
138
27.8k
    if (v < (U)0) { *value = (T)0; return;}
139
24.2k
    if (v > (U)max) { *value = (T)max; return;}
140
1.02k
    *value = (T)v;
141
1.02k
}
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
156
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
156
    using U = typename std::underlying_type<T>::type;
136
156
    U v;
137
156
    this->next(&v);
138
156
    if (v < (U)0) { *value = (T)0; return;}
139
71
    if (v > (U)max) { *value = (T)max; return;}
140
20
    *value = (T)v;
141
20
}
void Fuzz::nextEnum<GrSurfaceOrigin>(GrSurfaceOrigin*, GrSurfaceOrigin)
Line
Count
Source
131
156
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
156
    using U = typename std::underlying_type<T>::type;
136
156
    U v;
137
156
    this->next(&v);
138
156
    if (v < (U)0) { *value = (T)0; return;}
139
108
    if (v > (U)max) { *value = (T)max; return;}
140
69
    *value = (T)v;
141
69
}
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)
142
143
template <typename T>
144
209k
inline void Fuzz::nextN(T* ptr, int n) {
145
68.7M
   for (int i = 0; i < n; i++) {
146
68.5M
       this->next(ptr+i);
147
68.5M
   }
148
209k
}
void Fuzz::nextN<float>(float*, int)
Line
Count
Source
144
40.9k
inline void Fuzz::nextN(T* ptr, int n) {
145
664k
   for (int i = 0; i < n; i++) {
146
623k
       this->next(ptr+i);
147
623k
   }
148
40.9k
}
void Fuzz::nextN<unsigned char>(unsigned char*, int)
Line
Count
Source
144
26.6k
inline void Fuzz::nextN(T* ptr, int n) {
145
6.84M
   for (int i = 0; i < n; i++) {
146
6.81M
       this->next(ptr+i);
147
6.81M
   }
148
26.6k
}
void Fuzz::nextN<SkPoint>(SkPoint*, int)
Line
Count
Source
144
70.4k
inline void Fuzz::nextN(T* ptr, int n) {
145
891k
   for (int i = 0; i < n; i++) {
146
820k
       this->next(ptr+i);
147
820k
   }
148
70.4k
}
void Fuzz::nextN<int>(int*, int)
Line
Count
Source
144
1.77k
inline void Fuzz::nextN(T* ptr, int n) {
145
7.58k
   for (int i = 0; i < n; i++) {
146
5.81k
       this->next(ptr+i);
147
5.81k
   }
148
1.77k
}
void Fuzz::nextN<unsigned int>(unsigned int*, int)
Line
Count
Source
144
69.2k
inline void Fuzz::nextN(T* ptr, int n) {
145
60.3M
   for (int i = 0; i < n; i++) {
146
60.2M
       this->next(ptr+i);
147
60.2M
   }
148
69.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