/root/bitcoin/src/test/fuzz/integer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2019-2022 The Bitcoin Core developers |
2 | | // Distributed under the MIT software license, see the accompanying |
3 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | | |
5 | | #include <arith_uint256.h> |
6 | | #include <common/args.h> |
7 | | #include <common/system.h> |
8 | | #include <compressor.h> |
9 | | #include <consensus/amount.h> |
10 | | #include <consensus/merkle.h> |
11 | | #include <core_io.h> |
12 | | #include <crypto/common.h> |
13 | | #include <crypto/siphash.h> |
14 | | #include <key_io.h> |
15 | | #include <memusage.h> |
16 | | #include <netbase.h> |
17 | | #include <policy/policy.h> |
18 | | #include <policy/settings.h> |
19 | | #include <pow.h> |
20 | | #include <protocol.h> |
21 | | #include <pubkey.h> |
22 | | #include <script/script.h> |
23 | | #include <serialize.h> |
24 | | #include <streams.h> |
25 | | #include <test/fuzz/FuzzedDataProvider.h> |
26 | | #include <test/fuzz/fuzz.h> |
27 | | #include <test/fuzz/util.h> |
28 | | #include <uint256.h> |
29 | | #include <univalue.h> |
30 | | #include <util/chaintype.h> |
31 | | #include <util/check.h> |
32 | | #include <util/moneystr.h> |
33 | | #include <util/overflow.h> |
34 | | #include <util/strencodings.h> |
35 | | #include <util/string.h> |
36 | | |
37 | | #include <cassert> |
38 | | #include <chrono> |
39 | | #include <limits> |
40 | | #include <set> |
41 | | #include <vector> |
42 | | |
43 | | using util::ToString; |
44 | | |
45 | | void initialize_integer() |
46 | 0 | { |
47 | 0 | SelectParams(ChainType::REGTEST); |
48 | 0 | } |
49 | | |
50 | | FUZZ_TARGET(integer, .init = initialize_integer) |
51 | 0 | { |
52 | 0 | if (buffer.size() < sizeof(uint256) + sizeof(uint160)) { |
53 | 0 | return; |
54 | 0 | } |
55 | 0 | FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); |
56 | 0 | const uint256 u256(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint256))); |
57 | 0 | const uint160 u160(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint160))); |
58 | 0 | const uint64_t u64 = fuzzed_data_provider.ConsumeIntegral<uint64_t>(); |
59 | 0 | const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>(); |
60 | 0 | const uint32_t u32 = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); |
61 | 0 | const int32_t i32 = fuzzed_data_provider.ConsumeIntegral<int32_t>(); |
62 | 0 | const uint16_t u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>(); |
63 | 0 | const int16_t i16 = fuzzed_data_provider.ConsumeIntegral<int16_t>(); |
64 | 0 | const uint8_t u8 = fuzzed_data_provider.ConsumeIntegral<uint8_t>(); |
65 | 0 | const int8_t i8 = fuzzed_data_provider.ConsumeIntegral<int8_t>(); |
66 | | // We cannot assume a specific value of std::is_signed<char>::value: |
67 | | // ConsumeIntegral<char>() instead of casting from {u,}int8_t. |
68 | 0 | const char ch = fuzzed_data_provider.ConsumeIntegral<char>(); |
69 | 0 | const bool b = fuzzed_data_provider.ConsumeBool(); |
70 | |
|
71 | 0 | const Consensus::Params& consensus_params = Params().GetConsensus(); |
72 | 0 | (void)CheckProofOfWorkImpl(u256, u32, consensus_params); |
73 | 0 | if (u64 <= MAX_MONEY) { |
74 | 0 | const uint64_t compressed_money_amount = CompressAmount(u64); |
75 | 0 | assert(u64 == DecompressAmount(compressed_money_amount)); |
76 | 0 | static const uint64_t compressed_money_amount_max = CompressAmount(MAX_MONEY - 1); |
77 | 0 | assert(compressed_money_amount <= compressed_money_amount_max); |
78 | 0 | } else { |
79 | 0 | (void)CompressAmount(u64); |
80 | 0 | } |
81 | 0 | constexpr uint256 u256_min{"0000000000000000000000000000000000000000000000000000000000000000"}; |
82 | 0 | constexpr uint256 u256_max{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}; |
83 | 0 | const std::vector<uint256> v256{u256, u256_min, u256_max}; |
84 | 0 | (void)ComputeMerkleRoot(v256); |
85 | 0 | (void)DecompressAmount(u64); |
86 | 0 | { |
87 | 0 | if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) { |
88 | 0 | assert(parsed.value() == i64); |
89 | 0 | } |
90 | 0 | } |
91 | 0 | (void)GetSizeOfCompactSize(u64); |
92 | 0 | (void)GetSpecialScriptSize(u32); |
93 | 0 | if (!MultiplicationOverflow(i64, static_cast<int64_t>(u32)) && !AdditionOverflow(i64, static_cast<int64_t>(4)) && !AdditionOverflow(i64 * u32, static_cast<int64_t>(4))) { |
94 | 0 | (void)GetVirtualTransactionSize(i64, i64, u32); |
95 | 0 | } |
96 | 0 | (void)HexDigit(ch); |
97 | 0 | (void)MoneyRange(i64); |
98 | 0 | (void)ToString(i64); |
99 | 0 | (void)IsDigit(ch); |
100 | 0 | (void)IsSpace(ch); |
101 | 0 | (void)IsSwitchChar(ch); |
102 | 0 | (void)memusage::DynamicUsage(ch); |
103 | 0 | (void)memusage::DynamicUsage(i16); |
104 | 0 | (void)memusage::DynamicUsage(i32); |
105 | 0 | (void)memusage::DynamicUsage(i64); |
106 | 0 | (void)memusage::DynamicUsage(i8); |
107 | 0 | (void)memusage::DynamicUsage(u16); |
108 | 0 | (void)memusage::DynamicUsage(u32); |
109 | 0 | (void)memusage::DynamicUsage(u64); |
110 | 0 | (void)memusage::DynamicUsage(u8); |
111 | 0 | const unsigned char uch = static_cast<unsigned char>(u8); |
112 | 0 | (void)memusage::DynamicUsage(uch); |
113 | 0 | { |
114 | 0 | const std::set<int64_t> i64s{i64, static_cast<int64_t>(u64)}; |
115 | 0 | const size_t dynamic_usage = memusage::DynamicUsage(i64s); |
116 | 0 | const size_t incremental_dynamic_usage = memusage::IncrementalDynamicUsage(i64s); |
117 | 0 | assert(dynamic_usage == incremental_dynamic_usage * i64s.size()); |
118 | 0 | } |
119 | 0 | (void)MillisToTimeval(i64); |
120 | 0 | (void)SighashToStr(uch); |
121 | 0 | (void)SipHashUint256(u64, u64, u256); |
122 | 0 | (void)SipHashUint256Extra(u64, u64, u256, u32); |
123 | 0 | (void)ToLower(ch); |
124 | 0 | (void)ToUpper(ch); |
125 | 0 | { |
126 | 0 | if (std::optional<CAmount> parsed = ParseMoney(ValueFromAmount(i64).getValStr())) { |
127 | 0 | assert(parsed.value() == i64); |
128 | 0 | } |
129 | 0 | } |
130 | 0 | if (i32 >= 0 && i32 <= 16) { |
131 | 0 | assert(i32 == CScript::DecodeOP_N(CScript::EncodeOP_N(i32))); |
132 | 0 | } |
133 | | |
134 | 0 | const std::chrono::seconds seconds{i64}; |
135 | 0 | assert(count_seconds(seconds) == i64); |
136 | | |
137 | 0 | const CScriptNum script_num{i64}; |
138 | 0 | (void)script_num.getint(); |
139 | 0 | (void)script_num.getvch(); |
140 | |
|
141 | 0 | const arith_uint256 au256 = UintToArith256(u256); |
142 | 0 | assert(ArithToUint256(au256) == u256); |
143 | 0 | assert(uint256::FromHex(au256.GetHex()).value() == u256); |
144 | 0 | (void)au256.bits(); |
145 | 0 | (void)au256.GetCompact(/* fNegative= */ false); |
146 | 0 | (void)au256.GetCompact(/* fNegative= */ true); |
147 | 0 | (void)au256.getdouble(); |
148 | 0 | (void)au256.GetHex(); |
149 | 0 | (void)au256.GetLow64(); |
150 | 0 | (void)au256.size(); |
151 | 0 | (void)au256.ToString(); |
152 | |
|
153 | 0 | const CKeyID key_id{u160}; |
154 | 0 | const CScriptID script_id{u160}; |
155 | |
|
156 | 0 | { |
157 | 0 | DataStream stream{}; |
158 | |
|
159 | 0 | uint256 deserialized_u256; |
160 | 0 | stream << u256; |
161 | 0 | stream >> deserialized_u256; |
162 | 0 | assert(u256 == deserialized_u256 && stream.empty()); |
163 | | |
164 | 0 | uint160 deserialized_u160; |
165 | 0 | stream << u160; |
166 | 0 | stream >> deserialized_u160; |
167 | 0 | assert(u160 == deserialized_u160 && stream.empty()); |
168 | | |
169 | 0 | uint64_t deserialized_u64; |
170 | 0 | stream << u64; |
171 | 0 | stream >> deserialized_u64; |
172 | 0 | assert(u64 == deserialized_u64 && stream.empty()); |
173 | | |
174 | 0 | int64_t deserialized_i64; |
175 | 0 | stream << i64; |
176 | 0 | stream >> deserialized_i64; |
177 | 0 | assert(i64 == deserialized_i64 && stream.empty()); |
178 | | |
179 | 0 | uint32_t deserialized_u32; |
180 | 0 | stream << u32; |
181 | 0 | stream >> deserialized_u32; |
182 | 0 | assert(u32 == deserialized_u32 && stream.empty()); |
183 | | |
184 | 0 | int32_t deserialized_i32; |
185 | 0 | stream << i32; |
186 | 0 | stream >> deserialized_i32; |
187 | 0 | assert(i32 == deserialized_i32 && stream.empty()); |
188 | | |
189 | 0 | uint16_t deserialized_u16; |
190 | 0 | stream << u16; |
191 | 0 | stream >> deserialized_u16; |
192 | 0 | assert(u16 == deserialized_u16 && stream.empty()); |
193 | | |
194 | 0 | int16_t deserialized_i16; |
195 | 0 | stream << i16; |
196 | 0 | stream >> deserialized_i16; |
197 | 0 | assert(i16 == deserialized_i16 && stream.empty()); |
198 | | |
199 | 0 | uint8_t deserialized_u8; |
200 | 0 | stream << u8; |
201 | 0 | stream >> deserialized_u8; |
202 | 0 | assert(u8 == deserialized_u8 && stream.empty()); |
203 | | |
204 | 0 | int8_t deserialized_i8; |
205 | 0 | stream << i8; |
206 | 0 | stream >> deserialized_i8; |
207 | 0 | assert(i8 == deserialized_i8 && stream.empty()); |
208 | | |
209 | 0 | bool deserialized_b; |
210 | 0 | stream << b; |
211 | 0 | stream >> deserialized_b; |
212 | 0 | assert(b == deserialized_b && stream.empty()); |
213 | 0 | } |
214 | | |
215 | 0 | { |
216 | 0 | const ServiceFlags service_flags = (ServiceFlags)u64; |
217 | 0 | (void)MayHaveUsefulAddressDB(service_flags); |
218 | 0 | } |
219 | |
|
220 | 0 | { |
221 | 0 | DataStream stream{}; |
222 | |
|
223 | 0 | ser_writedata64(stream, u64); |
224 | 0 | const uint64_t deserialized_u64 = ser_readdata64(stream); |
225 | 0 | assert(u64 == deserialized_u64 && stream.empty()); |
226 | | |
227 | 0 | ser_writedata32(stream, u32); |
228 | 0 | const uint32_t deserialized_u32 = ser_readdata32(stream); |
229 | 0 | assert(u32 == deserialized_u32 && stream.empty()); |
230 | | |
231 | 0 | ser_writedata32be(stream, u32); |
232 | 0 | const uint32_t deserialized_u32be = ser_readdata32be(stream); |
233 | 0 | assert(u32 == deserialized_u32be && stream.empty()); |
234 | | |
235 | 0 | ser_writedata16(stream, u16); |
236 | 0 | const uint16_t deserialized_u16 = ser_readdata16(stream); |
237 | 0 | assert(u16 == deserialized_u16 && stream.empty()); |
238 | | |
239 | 0 | ser_writedata16be(stream, u16); |
240 | 0 | const uint16_t deserialized_u16be = ser_readdata16be(stream); |
241 | 0 | assert(u16 == deserialized_u16be && stream.empty()); |
242 | | |
243 | 0 | ser_writedata8(stream, u8); |
244 | 0 | const uint8_t deserialized_u8 = ser_readdata8(stream); |
245 | 0 | assert(u8 == deserialized_u8 && stream.empty()); |
246 | 0 | } |
247 | | |
248 | 0 | { |
249 | 0 | DataStream stream{}; |
250 | |
|
251 | 0 | WriteCompactSize(stream, u64); |
252 | 0 | try { |
253 | 0 | const uint64_t deserialized_u64 = ReadCompactSize(stream); |
254 | 0 | assert(u64 == deserialized_u64 && stream.empty()); |
255 | 0 | } catch (const std::ios_base::failure&) { |
256 | 0 | } |
257 | 0 | } |
258 | | |
259 | 0 | try { |
260 | 0 | CHECK_NONFATAL(b); |
261 | 0 | } catch (const NonFatalCheckError&) { |
262 | 0 | } |
263 | 0 | } |