Mutates Data in place, returns new size.
| 545 | |
| 546 | // Mutates Data in place, returns new size. |
| 547 | size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size, |
| 548 | size_t MaxSize, |
| 549 | std::vector<Mutator> &Mutators) { |
| 550 | assert(MaxSize > 0); |
| 551 | // Some mutations may fail (e.g. can't insert more bytes if Size == MaxSize), |
| 552 | // in which case they will return 0. |
| 553 | // Try several times before returning un-mutated data. |
| 554 | for (int Iter = 0; Iter < 100; Iter++) { |
| 555 | auto M = Mutators[Rand(Mutators.size())]; |
| 556 | size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize); |
| 557 | if (NewSize && NewSize <= MaxSize) { |
| 558 | if (Options.OnlyASCII) |
| 559 | ToASCII(Data, NewSize); |
| 560 | //CurrentMutatorSequence.push_back(M.Name); |
| 561 | return NewSize; |
| 562 | } |
| 563 | } |
| 564 | *Data = ' '; |
| 565 | return 1; // Fallback, should not happen frequently. |
| 566 | } |
| 567 | |
| 568 | // Mask represents the set of Data bytes that are worth mutating. |
| 569 | size_t MutationDispatcher::MutateWithMask(uint8_t *Data, size_t Size, |