Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(412)

Side by Side Diff: fuzz/Fuzz.h

Issue 2478593003: Avoid params being initialized out of order in Fuzzer (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « fuzz/FilterFuzz.cpp ('k') | fuzz/FuzzGradients.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef Fuzz_DEFINED 8 #ifndef Fuzz_DEFINED
9 #define Fuzz_DEFINED 9 #define Fuzz_DEFINED
10 10
11 #include "SkData.h" 11 #include "SkData.h"
12 #include "SkTRegistry.h" 12 #include "SkTRegistry.h"
13 #include "SkTypes.h" 13 #include "SkTypes.h"
14 14
15 #include <cmath> 15 #include <cmath>
16 16
17 class Fuzz : SkNoncopyable { 17 class Fuzz : SkNoncopyable {
18 public: 18 public:
19 explicit Fuzz(sk_sp<SkData>); 19 explicit Fuzz(sk_sp<SkData>);
20 20
21 // Returns the total number of "random" bytes available. 21 // Returns the total number of "random" bytes available.
22 size_t size(); 22 size_t size();
23 // Returns if there are no bytes remaining for fuzzing. 23 // Returns if there are no bytes remaining for fuzzing.
24 bool exhausted(); 24 bool exhausted();
25 25
26 // next() loads fuzzed bytes into the variable passed in by pointer.
27 // We use this approach instead of T next() because different compilers
28 // evaluate function parameters in different orders. If fuzz->next()
29 // returned 5 and then 7, foo(fuzz->next(), fuzz->next()) would be
30 // foo(5, 7) when compiled on GCC and foo(7, 5) when compiled on Clang.
31 // By requiring params to be passed in, we avoid any problems with
32 // non-determinism.
26 template <typename T> 33 template <typename T>
27 T next(); 34 void next(T* t);
35
36 // This is a convenient way to initialize more than one argument at a time.
37 template <typename Arg, typename... Args>
38 void next(Arg* first, Args... rest);
28 39
29 // nextRange returns values only in [min, max]. 40 // nextRange returns values only in [min, max].
30 template <typename T> 41 template <typename T>
31 T nextRange(T min, T max); 42 void nextRange(T* n, T min, T max);
32 43
33 void signalBug(); // Tell afl-fuzz these inputs found a bug. 44 void signalBug(); // Tell afl-fuzz these inputs found a bug.
34 45
35 private: 46 private:
36 template <typename T> 47 template <typename T>
37 T nextT(); 48 T nextT();
38 49
39 sk_sp<SkData> fBytes; 50 sk_sp<SkData> fBytes;
40 size_t fNextByte; 51 size_t fNextByte;
41 }; 52 };
42 53
43 // UBSAN reminds us that bool can only legally hold 0 or 1. 54 // UBSAN reminds us that bool can only legally hold 0 or 1.
44 template <> 55 template <>
45 inline bool Fuzz::next<bool>() { 56 inline void Fuzz::next(bool* b) {
46 return (this->next<uint8_t>() & 1) == 1; 57 uint8_t n;
58 this->next(&n);
59 *b = (n & 1) == 1;
47 } 60 }
48 61
49 template <typename T> 62 template <typename T>
50 T Fuzz::next() { 63 void Fuzz::next(T* n) {
51 if ((fNextByte + sizeof(T)) > fBytes->size()) { 64 if ((fNextByte + sizeof(T)) > fBytes->size()) {
52 T n = 0; 65 *n = 0;
53 memcpy(&n, fBytes->bytes() + fNextByte, fBytes->size() - fNextByte); 66 memcpy(n, fBytes->bytes() + fNextByte, fBytes->size() - fNextByte);
54 fNextByte = fBytes->size(); 67 fNextByte = fBytes->size();
55 return n; 68 return;
56 } 69 }
57 T n; 70 memcpy(n, fBytes->bytes() + fNextByte, sizeof(T));
58 memcpy(&n, fBytes->bytes() + fNextByte, sizeof(T));
59 fNextByte += sizeof(T); 71 fNextByte += sizeof(T);
60 return n; 72 }
73
74 template <typename Arg, typename... Args>
75 void Fuzz::next(Arg* first, Args... rest) {
76 this->next(first);
77 this->next(rest...);
61 } 78 }
62 79
63 template <> 80 template <>
64 inline float Fuzz::nextRange(float min, float max) { 81 inline void Fuzz::nextRange(float* f, float min, float max) {
65 if (min > max) { 82 if (min > max) {
66 SkDebugf("Check mins and maxes (%f, %f)\n", min, max); 83 SkDebugf("Check mins and maxes (%f, %f)\n", min, max);
67 this->signalBug(); 84 this->signalBug();
68 } 85 }
69 float f = this->next<float>(); 86 this->next<float>(f);
70 if (!std::isnormal(f) && f != 0.0f) { 87 if (!std::isnormal(*f) && *f != 0.0f) {
71 // Don't deal with infinity or other strange floats. 88 // Don't deal with infinity or other strange floats.
72 return max; 89 *f = max;
73 } 90 }
74 return min + std::fmod(std::abs(f), (max - min + 1)); 91 *f = min + std::fmod(std::abs(*f), (max - min + 1));
75 } 92 }
76 93
77 template <typename T> 94 template <typename T>
78 T Fuzz::nextRange(T min, T max) { 95 void Fuzz::nextRange(T* n, T min, T max) {
79 if (min > max) { 96 if (min > max) {
80 SkDebugf("Check mins and maxes (%d, %d)\n", min, max); 97 SkDebugf("Check mins and maxes (%d, %d)\n", min, max);
81 this->signalBug(); 98 this->signalBug();
82 } 99 }
83 T n = this->next<T>(); 100 this->next<T>(n);
84 T range = max - min + 1; 101 T range = max - min + 1;
85 if (0 == range) { 102 if (0 == range) {
86 return n; 103 return;
87 } else { 104 } else {
88 n = abs(n); 105 *n = abs(*n);
89 if (n < 0) { 106 if (*n < 0) {
90 // abs(INT_MIN) = INT_MIN, so we check this to avoid accidental negati ves. 107 // abs(INT_MIN) = INT_MIN, so we check this to avoid accidental negati ves.
91 return min; 108 *n = min;
109 return;
92 } 110 }
93 return min + n % range; 111 *n = min + *n % range;
94 } 112 }
95 } 113 }
96 114
97 struct Fuzzable { 115 struct Fuzzable {
98 const char* name; 116 const char* name;
99 void (*fn)(Fuzz*); 117 void (*fn)(Fuzz*);
100 }; 118 };
101 119
102 #define DEF_FUZZ(name, f) \ 120 #define DEF_FUZZ(name, f) \
103 static void fuzz_##name(Fuzz*); \ 121 static void fuzz_##name(Fuzz*); \
104 SkTRegistry<Fuzzable> register_##name({#name, fuzz_##name}); \ 122 SkTRegistry<Fuzzable> register_##name({#name, fuzz_##name}); \
105 static void fuzz_##name(Fuzz* f) 123 static void fuzz_##name(Fuzz* f)
106 124
107 #endif//Fuzz_DEFINED 125 #endif//Fuzz_DEFINED
OLDNEW
« no previous file with comments | « fuzz/FilterFuzz.cpp ('k') | fuzz/FuzzGradients.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698