Skip to content

Commit 3f6729b

Browse files
authored
Fuzzer: Do not always add functions (#7917)
Leaving a small chance to only modify existing functions, rather than always add lots of new ones, opens opportunities for very precise small testcases to not get overly-modified. E.g., if a small testcase checks for turning a field immutable, adding many functions will likely add sets to all fields, changing the global picture substantially.
1 parent e6f3dec commit 3f6729b

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

src/tools/fuzzing.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ class TranslateToFuzzReader {
219219
// The name of an empty tag.
220220
Name trivialTag;
221221

222+
// Whether we were given initial functions.
223+
bool haveInitialFunctions;
224+
222225
// RAII helper for managing the state used to create a single function.
223226
struct FunctionCreationContext {
224227
TranslateToFuzzReader& parent;

src/tools/fuzzing/fuzzing.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ TranslateToFuzzReader::TranslateToFuzzReader(Module& wasm,
3333
random(std::move(input), wasm.features),
3434
publicTypeValidator(wasm.features) {
3535

36+
haveInitialFunctions = !wasm.functions.empty();
37+
3638
// - funcref cannot be logged because referenced functions can be inlined or
3739
// removed during optimization
3840
// - there's no point in logging anyref because it is opaque
@@ -1391,6 +1393,14 @@ void TranslateToFuzzReader::processFunctions() {
13911393
const int RESOLUTION = 10;
13921394
auto chance = upTo(RESOLUTION + 1);
13931395

1396+
// We do not want to always add new functions, if there are initial ones:
1397+
// adding many additional functions will cause a lot of global properties to
1398+
// change, e.g., if the initial content was a carefully crafted testcase
1399+
// showing some situation of reads and writes between struct fields, adding
1400+
// many new functions will likely add reads and writes to all the fields,
1401+
// preventing global operations like field removal or immutabilification.
1402+
auto allowNew = !haveInitialFunctions || !oneIn(10);
1403+
13941404
// Keep working while we have random data.
13951405
while (!random.finished()) {
13961406
if (!moddable.empty() && upTo(RESOLUTION) < chance) {
@@ -1403,7 +1413,7 @@ void TranslateToFuzzReader::processFunctions() {
14031413
// place, and truncating.
14041414
moddable[index] = moddable.back();
14051415
moddable.pop_back();
1406-
} else {
1416+
} else if (allowNew) {
14071417
// Add a new function
14081418
auto* func = addFunction();
14091419
addInvocations(func);
@@ -1413,6 +1423,10 @@ void TranslateToFuzzReader::processFunctions() {
14131423
if (allowOOB) {
14141424
moddable.push_back(func);
14151425
}
1426+
} else {
1427+
// If we found nothing to do, consume some data so that we make progress
1428+
// towards the loop ending.
1429+
get();
14161430
}
14171431
}
14181432

0 commit comments

Comments
 (0)