fuzz: make FuzzedDataProvider usage deterministic

There exist many usages of `fuzzed_data_provider` where it is evaluated directly in the function call.
Unfortunately, the order of evaluation of function arguments is unspecified. This means it can differ
between compilers/version/optimization levels etc. But when the evaluation order changes, the same
fuzzing input will produce different output, which is bad for coverage/reproducibility.

This PR fixes all these cases where by moving multiple calls to `fuzzed_data_provider` out of the
function arguments.
This commit is contained in:
Martin Leitner-Ankerl
2023-12-09 13:19:02 +01:00
parent 3e691258d8
commit 01960c53c7
18 changed files with 129 additions and 66 deletions

View File

@@ -212,15 +212,20 @@ FUZZ_TARGET(prevector)
LIMITED_WHILE(prov.remaining_bytes(), 3000)
{
switch (prov.ConsumeIntegralInRange<int>(0, 13 + 3 * (test.size() > 0))) {
case 0:
test.insert(prov.ConsumeIntegralInRange<size_t>(0, test.size()), prov.ConsumeIntegral<int>());
break;
case 0: {
auto position = prov.ConsumeIntegralInRange<size_t>(0, test.size());
auto value = prov.ConsumeIntegral<int>();
test.insert(position, value);
} break;
case 1:
test.resize(std::max(0, std::min(30, (int)test.size() + prov.ConsumeIntegralInRange<int>(0, 4) - 2)));
break;
case 2:
test.insert(prov.ConsumeIntegralInRange<size_t>(0, test.size()), 1 + prov.ConsumeBool(), prov.ConsumeIntegral<int>());
break;
case 2: {
auto position = prov.ConsumeIntegralInRange<size_t>(0, test.size());
auto count = 1 + prov.ConsumeBool();
auto value = prov.ConsumeIntegral<int>();
test.insert(position, count, value);
} break;
case 3: {
int del = prov.ConsumeIntegralInRange<int>(0, test.size());
int beg = prov.ConsumeIntegralInRange<int>(0, test.size() - del);
@@ -257,9 +262,11 @@ FUZZ_TARGET(prevector)
case 9:
test.clear();
break;
case 10:
test.assign(prov.ConsumeIntegralInRange<size_t>(0, 32767), prov.ConsumeIntegral<int>());
break;
case 10: {
auto n = prov.ConsumeIntegralInRange<size_t>(0, 32767);
auto value = prov.ConsumeIntegral<int>();
test.assign(n, value);
} break;
case 11:
test.swap();
break;
@@ -269,9 +276,11 @@ FUZZ_TARGET(prevector)
case 13:
test.move();
break;
case 14:
test.update(prov.ConsumeIntegralInRange<size_t>(0, test.size() - 1), prov.ConsumeIntegral<int>());
break;
case 14: {
auto pos = prov.ConsumeIntegralInRange<size_t>(0, test.size() - 1);
auto value = prov.ConsumeIntegral<int>();
test.update(pos, value);
} break;
case 15:
test.erase(prov.ConsumeIntegralInRange<size_t>(0, test.size() - 1));
break;