Skip to content

Commit 29d2aeb

Browse files
author
MarcoFalke
committed
Merge #20828: fuzz: Introduce CallOneOf helper to replace switch-case
fa75d40 fuzz: Introduce CallOneOf helper to replace switch-case (MarcoFalke) Pull request description: The current `switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, nn)) { case 0: ... case 1: ... case nn: ...` has several problems: * It makes it hard to review newly added targets, because it requires manual counting of cases * It makes it hard to update a target, because updating all case labels is trivial, but tedious to review and causes merge conflicts * ~~Updating the target raises the question whether the case labels should be preserved to not invalidate the existing fuzz inputs format. Fuzz input format might already change implicitly on every commit, so this isn't something worthwhile to pursue.~~ Edit: This pull doesn't fix this problem. Fix all issues by adding a new `CallOneOf` helper ACKs for top commit: ajtowns: ACK fa75d40 - code review only jnewbery: utACK fa75d40 Tree-SHA512: 2daa602b240b86c8e85a024e008f03a57ba60349377eed771f4d21a97a9dba9b66e93fff16ff1992018d4330be7a1a276944c3dfdf698748ce135626c380e563
2 parents ad571bd + fa75d40 commit 29d2aeb

19 files changed

+1094
-1214
lines changed

src/test/fuzz/addrman.cpp

Lines changed: 63 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -45,83 +45,71 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman)
4545
}
4646
}
4747
while (fuzzed_data_provider.ConsumeBool()) {
48-
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
49-
case 0: {
50-
addr_man.Clear();
51-
break;
52-
}
53-
case 1: {
54-
addr_man.ResolveCollisions();
55-
break;
56-
}
57-
case 2: {
58-
(void)addr_man.SelectTriedCollision();
59-
break;
60-
}
61-
case 3: {
62-
(void)addr_man.Select(fuzzed_data_provider.ConsumeBool());
63-
break;
64-
}
65-
case 4: {
66-
(void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
67-
break;
68-
}
69-
case 5: {
70-
const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
71-
const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
72-
if (opt_address && opt_net_addr) {
73-
addr_man.Add(*opt_address, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
74-
}
75-
break;
76-
}
77-
case 6: {
78-
std::vector<CAddress> addresses;
79-
while (fuzzed_data_provider.ConsumeBool()) {
48+
CallOneOf(
49+
fuzzed_data_provider,
50+
[&] {
51+
addr_man.Clear();
52+
},
53+
[&] {
54+
addr_man.ResolveCollisions();
55+
},
56+
[&] {
57+
(void)addr_man.SelectTriedCollision();
58+
},
59+
[&] {
60+
(void)addr_man.Select(fuzzed_data_provider.ConsumeBool());
61+
},
62+
[&] {
63+
(void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
64+
},
65+
[&] {
8066
const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
81-
if (!opt_address) {
82-
break;
67+
const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
68+
if (opt_address && opt_net_addr) {
69+
addr_man.Add(*opt_address, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
8370
}
84-
addresses.push_back(*opt_address);
85-
}
86-
const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
87-
if (opt_net_addr) {
88-
addr_man.Add(addresses, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
89-
}
90-
break;
91-
}
92-
case 7: {
93-
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
94-
if (opt_service) {
95-
addr_man.Good(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
96-
}
97-
break;
98-
}
99-
case 8: {
100-
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
101-
if (opt_service) {
102-
addr_man.Attempt(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
103-
}
104-
break;
105-
}
106-
case 9: {
107-
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
108-
if (opt_service) {
109-
addr_man.Connected(*opt_service, ConsumeTime(fuzzed_data_provider));
110-
}
111-
break;
112-
}
113-
case 10: {
114-
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
115-
if (opt_service) {
116-
addr_man.SetServices(*opt_service, ServiceFlags{fuzzed_data_provider.ConsumeIntegral<uint64_t>()});
117-
}
118-
break;
119-
}
120-
case 11: {
121-
(void)addr_man.Check();
122-
break;
123-
}
124-
}
71+
},
72+
[&] {
73+
std::vector<CAddress> addresses;
74+
while (fuzzed_data_provider.ConsumeBool()) {
75+
const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
76+
if (!opt_address) {
77+
break;
78+
}
79+
addresses.push_back(*opt_address);
80+
}
81+
const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
82+
if (opt_net_addr) {
83+
addr_man.Add(addresses, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
84+
}
85+
},
86+
[&] {
87+
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
88+
if (opt_service) {
89+
addr_man.Good(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
90+
}
91+
},
92+
[&] {
93+
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
94+
if (opt_service) {
95+
addr_man.Attempt(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
96+
}
97+
},
98+
[&] {
99+
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
100+
if (opt_service) {
101+
addr_man.Connected(*opt_service, ConsumeTime(fuzzed_data_provider));
102+
}
103+
},
104+
[&] {
105+
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
106+
if (opt_service) {
107+
addr_man.SetServices(*opt_service, ServiceFlags{fuzzed_data_provider.ConsumeIntegral<uint64_t>()});
108+
}
109+
},
110+
[&] {
111+
(void)addr_man.Check();
112+
});
125113
}
126114
(void)addr_man.size();
127115
CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);

src/test/fuzz/autofile.cpp

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,43 +21,37 @@ FUZZ_TARGET(autofile)
2121
FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
2222
CAutoFile auto_file = fuzzed_auto_file_provider.open();
2323
while (fuzzed_data_provider.ConsumeBool()) {
24-
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
25-
case 0: {
26-
std::array<uint8_t, 4096> arr{};
27-
try {
28-
auto_file.read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
29-
} catch (const std::ios_base::failure&) {
30-
}
31-
break;
32-
}
33-
case 1: {
34-
const std::array<uint8_t, 4096> arr{};
35-
try {
36-
auto_file.write((const char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
37-
} catch (const std::ios_base::failure&) {
38-
}
39-
break;
40-
}
41-
case 2: {
42-
try {
43-
auto_file.ignore(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
44-
} catch (const std::ios_base::failure&) {
45-
}
46-
break;
47-
}
48-
case 3: {
49-
auto_file.fclose();
50-
break;
51-
}
52-
case 4: {
53-
ReadFromStream(fuzzed_data_provider, auto_file);
54-
break;
55-
}
56-
case 5: {
57-
WriteToStream(fuzzed_data_provider, auto_file);
58-
break;
59-
}
60-
}
24+
CallOneOf(
25+
fuzzed_data_provider,
26+
[&] {
27+
std::array<uint8_t, 4096> arr{};
28+
try {
29+
auto_file.read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
30+
} catch (const std::ios_base::failure&) {
31+
}
32+
},
33+
[&] {
34+
const std::array<uint8_t, 4096> arr{};
35+
try {
36+
auto_file.write((const char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
37+
} catch (const std::ios_base::failure&) {
38+
}
39+
},
40+
[&] {
41+
try {
42+
auto_file.ignore(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
43+
} catch (const std::ios_base::failure&) {
44+
}
45+
},
46+
[&] {
47+
auto_file.fclose();
48+
},
49+
[&] {
50+
ReadFromStream(fuzzed_data_provider, auto_file);
51+
},
52+
[&] {
53+
WriteToStream(fuzzed_data_provider, auto_file);
54+
});
6155
}
6256
(void)auto_file.Get();
6357
(void)auto_file.GetType();

src/test/fuzz/banman.cpp

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -38,51 +38,43 @@ FUZZ_TARGET_INIT(banman, initialize_banman)
3838
{
3939
BanMan ban_man{banlist_file, nullptr, ConsumeBanTimeOffset(fuzzed_data_provider)};
4040
while (fuzzed_data_provider.ConsumeBool()) {
41-
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
42-
case 0: {
43-
ban_man.Ban(ConsumeNetAddr(fuzzed_data_provider),
44-
ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
45-
break;
46-
}
47-
case 1: {
48-
ban_man.Ban(ConsumeSubNet(fuzzed_data_provider),
49-
ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
50-
break;
51-
}
52-
case 2: {
53-
ban_man.ClearBanned();
54-
break;
55-
}
56-
case 4: {
57-
ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider));
58-
break;
59-
}
60-
case 5: {
61-
ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider));
62-
break;
63-
}
64-
case 6: {
65-
ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider));
66-
break;
67-
}
68-
case 7: {
69-
ban_man.Unban(ConsumeSubNet(fuzzed_data_provider));
70-
break;
71-
}
72-
case 8: {
73-
banmap_t banmap;
74-
ban_man.GetBanned(banmap);
75-
break;
76-
}
77-
case 9: {
78-
ban_man.DumpBanlist();
79-
break;
80-
}
81-
case 11: {
82-
ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));
83-
break;
84-
}
85-
}
41+
CallOneOf(
42+
fuzzed_data_provider,
43+
[&] {
44+
ban_man.Ban(ConsumeNetAddr(fuzzed_data_provider),
45+
ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
46+
},
47+
[&] {
48+
ban_man.Ban(ConsumeSubNet(fuzzed_data_provider),
49+
ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
50+
},
51+
[&] {
52+
ban_man.ClearBanned();
53+
},
54+
[] {},
55+
[&] {
56+
ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider));
57+
},
58+
[&] {
59+
ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider));
60+
},
61+
[&] {
62+
ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider));
63+
},
64+
[&] {
65+
ban_man.Unban(ConsumeSubNet(fuzzed_data_provider));
66+
},
67+
[&] {
68+
banmap_t banmap;
69+
ban_man.GetBanned(banmap);
70+
},
71+
[&] {
72+
ban_man.DumpBanlist();
73+
},
74+
[] {},
75+
[&] {
76+
ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));
77+
});
8678
}
8779
}
8880
fs::remove(banlist_file);

src/test/fuzz/bloom_filter.cpp

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -25,47 +25,43 @@ FUZZ_TARGET(bloom_filter)
2525
fuzzed_data_provider.ConsumeIntegral<unsigned int>(),
2626
static_cast<unsigned char>(fuzzed_data_provider.PickValueInArray({BLOOM_UPDATE_NONE, BLOOM_UPDATE_ALL, BLOOM_UPDATE_P2PUBKEY_ONLY, BLOOM_UPDATE_MASK}))};
2727
while (fuzzed_data_provider.remaining_bytes() > 0) {
28-
switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 3)) {
29-
case 0: {
30-
const std::vector<unsigned char> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
31-
(void)bloom_filter.contains(b);
32-
bloom_filter.insert(b);
33-
const bool present = bloom_filter.contains(b);
34-
assert(present);
35-
break;
36-
}
37-
case 1: {
38-
const std::optional<COutPoint> out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
39-
if (!out_point) {
40-
break;
41-
}
42-
(void)bloom_filter.contains(*out_point);
43-
bloom_filter.insert(*out_point);
44-
const bool present = bloom_filter.contains(*out_point);
45-
assert(present);
46-
break;
47-
}
48-
case 2: {
49-
const std::optional<uint256> u256 = ConsumeDeserializable<uint256>(fuzzed_data_provider);
50-
if (!u256) {
51-
break;
52-
}
53-
(void)bloom_filter.contains(*u256);
54-
bloom_filter.insert(*u256);
55-
const bool present = bloom_filter.contains(*u256);
56-
assert(present);
57-
break;
58-
}
59-
case 3: {
60-
const std::optional<CMutableTransaction> mut_tx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
61-
if (!mut_tx) {
62-
break;
63-
}
64-
const CTransaction tx{*mut_tx};
65-
(void)bloom_filter.IsRelevantAndUpdate(tx);
66-
break;
67-
}
68-
}
28+
CallOneOf(
29+
fuzzed_data_provider,
30+
[&] {
31+
const std::vector<unsigned char> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
32+
(void)bloom_filter.contains(b);
33+
bloom_filter.insert(b);
34+
const bool present = bloom_filter.contains(b);
35+
assert(present);
36+
},
37+
[&] {
38+
const std::optional<COutPoint> out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
39+
if (!out_point) {
40+
return;
41+
}
42+
(void)bloom_filter.contains(*out_point);
43+
bloom_filter.insert(*out_point);
44+
const bool present = bloom_filter.contains(*out_point);
45+
assert(present);
46+
},
47+
[&] {
48+
const std::optional<uint256> u256 = ConsumeDeserializable<uint256>(fuzzed_data_provider);
49+
if (!u256) {
50+
return;
51+
}
52+
(void)bloom_filter.contains(*u256);
53+
bloom_filter.insert(*u256);
54+
const bool present = bloom_filter.contains(*u256);
55+
assert(present);
56+
},
57+
[&] {
58+
const std::optional<CMutableTransaction> mut_tx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
59+
if (!mut_tx) {
60+
return;
61+
}
62+
const CTransaction tx{*mut_tx};
63+
(void)bloom_filter.IsRelevantAndUpdate(tx);
64+
});
6965
(void)bloom_filter.IsWithinSizeConstraints();
7066
}
7167
}

0 commit comments

Comments
 (0)