Skip to content

Commit ab2df17

Browse files
committed
Merge bitcoin#31917: fuzz: provide more realistic values to the base58(check) decoders
d5537c1 fuzz: make sure DecodeBase58(Check) is called with valid values more often (Lőrinc) bad1433 fuzz: Always restrict base conversion input lengths (Lőrinc) Pull request description: This is a follow-up to bitcoin#30746, expanding coverage by: * restricting every input for the base58 conversions, capping max sizes to `100` instead of `1000` or all available input (suggested by marcofleon in bitcoin#30746 (comment)) since most actual usage has lengths of e.g. `21`, `34`, `78`. * providing more valid values to the decoder (suggested by maflcko in bitcoin#30746 (comment)) by randomly providing a random input or a valid encoded one; this also enables unifying the roundtrip tests to a single roundtrip per fuzz. ACKs for top commit: mzumsande: Code Review / lightly tested ACK d5537c1 maflcko: review ACK d5537c1 🚛 Tree-SHA512: 50365654cdac8a38708a7475eaa43396642b7337e2ee8999374c3faafff4f05457abc1a54c701211e0ed24d36c12af77bcad17b49695699be42664f2be660659
2 parents 51a20e5 + d5537c1 commit ab2df17

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

src/test/fuzz/base_encode_decode.cpp

+25-26
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <base58.h>
88
#include <psbt.h>
9+
#include <span.h>
910
#include <test/fuzz/FuzzedDataProvider.h>
1011
#include <util/strencodings.h>
1112
#include <util/string.h>
@@ -19,42 +20,40 @@ using util::TrimStringView;
1920

2021
FUZZ_TARGET(base58_encode_decode)
2122
{
22-
FuzzedDataProvider provider(buffer.data(), buffer.size());
23-
const std::string random_string{provider.ConsumeRandomLengthString(1000)};
24-
const int max_ret_len{provider.ConsumeIntegralInRange<int>(-1, 1000)};
23+
FuzzedDataProvider provider{buffer.data(), buffer.size()};
24+
const auto random_string{provider.ConsumeRandomLengthString(100)};
2525

26-
// Decode/Encode roundtrip
27-
std::vector<unsigned char> decoded;
28-
if (DecodeBase58(random_string, decoded, max_ret_len)) {
26+
const auto encoded{EncodeBase58(MakeUCharSpan(random_string))};
27+
const auto decode_input{provider.ConsumeBool() ? random_string : encoded};
28+
const int max_ret_len{provider.ConsumeIntegralInRange<int>(-1, decode_input.size() + 1)};
29+
if (std::vector<unsigned char> decoded; DecodeBase58(decode_input, decoded, max_ret_len)) {
2930
const auto encoded_string{EncodeBase58(decoded)};
30-
assert(encoded_string == TrimStringView(random_string));
31-
assert(encoded_string.empty() || !DecodeBase58(encoded_string, decoded, provider.ConsumeIntegralInRange<int>(0, decoded.size() - 1)));
31+
assert(encoded_string == TrimStringView(decode_input));
32+
if (decoded.size() > 0) {
33+
assert(max_ret_len > 0);
34+
assert(decoded.size() <= static_cast<size_t>(max_ret_len));
35+
assert(!DecodeBase58(encoded_string, decoded, provider.ConsumeIntegralInRange<int>(0, decoded.size() - 1)));
36+
}
3237
}
33-
// Encode/Decode roundtrip
34-
const auto encoded{EncodeBase58(buffer)};
35-
std::vector<unsigned char> roundtrip_decoded;
36-
assert(DecodeBase58(encoded, roundtrip_decoded, buffer.size())
37-
&& std::ranges::equal(roundtrip_decoded, buffer));
3838
}
3939

4040
FUZZ_TARGET(base58check_encode_decode)
4141
{
42-
FuzzedDataProvider provider(buffer.data(), buffer.size());
43-
const std::string random_string{provider.ConsumeRandomLengthString(1000)};
44-
const int max_ret_len{provider.ConsumeIntegralInRange<int>(-1, 1000)};
42+
FuzzedDataProvider provider{buffer.data(), buffer.size()};
43+
const auto random_string{provider.ConsumeRandomLengthString(100)};
4544

46-
// Decode/Encode roundtrip
47-
std::vector<unsigned char> decoded;
48-
if (DecodeBase58Check(random_string, decoded, max_ret_len)) {
45+
const auto encoded{EncodeBase58Check(MakeUCharSpan(random_string))};
46+
const auto decode_input{provider.ConsumeBool() ? random_string : encoded};
47+
const int max_ret_len{provider.ConsumeIntegralInRange<int>(-1, decode_input.size() + 1)};
48+
if (std::vector<unsigned char> decoded; DecodeBase58Check(decode_input, decoded, max_ret_len)) {
4949
const auto encoded_string{EncodeBase58Check(decoded)};
50-
assert(encoded_string == TrimStringView(random_string));
51-
assert(encoded_string.empty() || !DecodeBase58Check(encoded_string, decoded, provider.ConsumeIntegralInRange<int>(0, decoded.size() - 1)));
50+
assert(encoded_string == TrimStringView(decode_input));
51+
if (decoded.size() > 0) {
52+
assert(max_ret_len > 0);
53+
assert(decoded.size() <= static_cast<size_t>(max_ret_len));
54+
assert(!DecodeBase58Check(encoded_string, decoded, provider.ConsumeIntegralInRange<int>(0, decoded.size() - 1)));
55+
}
5256
}
53-
// Encode/Decode roundtrip
54-
const auto encoded{EncodeBase58Check(buffer)};
55-
std::vector<unsigned char> roundtrip_decoded;
56-
assert(DecodeBase58Check(encoded, roundtrip_decoded, buffer.size())
57-
&& std::ranges::equal(roundtrip_decoded, buffer));
5857
}
5958

6059
FUZZ_TARGET(base32_encode_decode)

0 commit comments

Comments
 (0)