// Mutate a test input.
//===----------------------------------------------------------------------===//
+#include <cstring>
+
#include "FuzzerInternal.h"
namespace fuzzer {
return Special[rand() % (sizeof(Special) - 1)];
}
-void Mutate(Unit *U, size_t MaxLen) {
- assert(MaxLen > 0);
- assert(U->size() <= MaxLen);
+// Mutates Data in place, returns new size.
+size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
+ assert(MaxSize > 0);
+ assert(Size <= MaxSize);
+ if (Size == 0) {
+ for (size_t i = 0; i < MaxSize; i++)
+ Data[i] = RandCh();
+ return MaxSize;
+ }
+ assert(Size > 0);
+ size_t Idx = rand() % Size;
switch (rand() % 3) {
case 0:
- if (U->size())
- U->erase(U->begin() + rand() % U->size());
- break;
+ if (Size > 1) {
+ // Erase Data[Idx].
+ memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
+ Size = Size - 1;
+ }
+ [[clang::fallthrough]];
case 1:
- if (U->empty()) {
- U->push_back(RandCh());
- } else if (U->size() < MaxLen) {
- U->insert(U->begin() + rand() % U->size(), RandCh());
- } else { // At MaxLen.
- uint8_t Ch = RandCh();
- size_t Idx = rand() % U->size();
- (*U)[Idx] = Ch;
+ if (Size < MaxSize) {
+ // Insert new value at Data[Idx].
+ memmove(Data + Idx + 1, Data + Idx, Size - Idx);
+ Data[Idx] = RandCh();
}
+ Data[Idx] = RandCh();
break;
- default:
- if (!U->empty()) {
- size_t idx = rand() % U->size();
- (*U)[idx] = FlipRandomBit((*U)[idx]);
- }
+ case 2:
+ Data[Idx] = FlipRandomBit(Data[Idx]);
break;
}
+ assert(Size > 0);
+ return Size;
}
} // namespace fuzzer