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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « fuzz/FilterFuzz.cpp ('k') | fuzz/FuzzGradients.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: fuzz/Fuzz.h
diff --git a/fuzz/Fuzz.h b/fuzz/Fuzz.h
index 17d75f4d3480edafe8e612c7a19984a976c0c970..013d8fef52bb5d392b5dd806221adfb9a0b3b7bb 100644
--- a/fuzz/Fuzz.h
+++ b/fuzz/Fuzz.h
@@ -23,12 +23,23 @@ public:
// Returns if there are no bytes remaining for fuzzing.
bool exhausted();
+ // next() loads fuzzed bytes into the variable passed in by pointer.
+ // We use this approach instead of T next() because different compilers
+ // evaluate function parameters in different orders. If fuzz->next()
+ // returned 5 and then 7, foo(fuzz->next(), fuzz->next()) would be
+ // foo(5, 7) when compiled on GCC and foo(7, 5) when compiled on Clang.
+ // By requiring params to be passed in, we avoid any problems with
+ // non-determinism.
template <typename T>
- T next();
+ void next(T* t);
+
+ // This is a convenient way to initialize more than one argument at a time.
+ template <typename Arg, typename... Args>
+ void next(Arg* first, Args... rest);
// nextRange returns values only in [min, max].
template <typename T>
- T nextRange(T min, T max);
+ void nextRange(T* n, T min, T max);
void signalBug(); // Tell afl-fuzz these inputs found a bug.
@@ -42,55 +53,62 @@ private:
// UBSAN reminds us that bool can only legally hold 0 or 1.
template <>
-inline bool Fuzz::next<bool>() {
- return (this->next<uint8_t>() & 1) == 1;
+inline void Fuzz::next(bool* b) {
+ uint8_t n;
+ this->next(&n);
+ *b = (n & 1) == 1;
}
template <typename T>
-T Fuzz::next() {
+void Fuzz::next(T* n) {
if ((fNextByte + sizeof(T)) > fBytes->size()) {
- T n = 0;
- memcpy(&n, fBytes->bytes() + fNextByte, fBytes->size() - fNextByte);
+ *n = 0;
+ memcpy(n, fBytes->bytes() + fNextByte, fBytes->size() - fNextByte);
fNextByte = fBytes->size();
- return n;
+ return;
}
- T n;
- memcpy(&n, fBytes->bytes() + fNextByte, sizeof(T));
+ memcpy(n, fBytes->bytes() + fNextByte, sizeof(T));
fNextByte += sizeof(T);
- return n;
+}
+
+template <typename Arg, typename... Args>
+void Fuzz::next(Arg* first, Args... rest) {
+ this->next(first);
+ this->next(rest...);
}
template <>
-inline float Fuzz::nextRange(float min, float max) {
+inline void Fuzz::nextRange(float* f, float min, float max) {
if (min > max) {
SkDebugf("Check mins and maxes (%f, %f)\n", min, max);
this->signalBug();
}
- float f = this->next<float>();
- if (!std::isnormal(f) && f != 0.0f) {
+ this->next<float>(f);
+ if (!std::isnormal(*f) && *f != 0.0f) {
// Don't deal with infinity or other strange floats.
- return max;
+ *f = max;
}
- return min + std::fmod(std::abs(f), (max - min + 1));
+ *f = min + std::fmod(std::abs(*f), (max - min + 1));
}
template <typename T>
-T Fuzz::nextRange(T min, T max) {
+void Fuzz::nextRange(T* n, T min, T max) {
if (min > max) {
SkDebugf("Check mins and maxes (%d, %d)\n", min, max);
this->signalBug();
}
- T n = this->next<T>();
+ this->next<T>(n);
T range = max - min + 1;
if (0 == range) {
- return n;
+ return;
} else {
- n = abs(n);
- if (n < 0) {
+ *n = abs(*n);
+ if (*n < 0) {
// abs(INT_MIN) = INT_MIN, so we check this to avoid accidental negatives.
- return min;
+ *n = min;
+ return;
}
- return min + n % range;
+ *n = min + *n % range;
}
}
« 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