tests: Add missing locks to tests
[bitcoinplatinum.git] / src / test / test_bitcoin_fuzzy.cpp
blob6694c5caa85c928d2a9e2c4b29de59397d973fa5
1 // Copyright (c) 2009-2016 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.
5 #if defined(HAVE_CONFIG_H)
6 #include "config/bitcoin-config.h"
7 #endif
9 #include "consensus/merkle.h"
10 #include "primitives/block.h"
11 #include "script/script.h"
12 #include "addrman.h"
13 #include "chain.h"
14 #include "coins.h"
15 #include "compressor.h"
16 #include "net.h"
17 #include "protocol.h"
18 #include "streams.h"
19 #include "undo.h"
20 #include "version.h"
21 #include "pubkey.h"
22 #include "blockencodings.h"
24 #include <stdint.h>
25 #include <unistd.h>
27 #include <algorithm>
28 #include <vector>
30 enum TEST_ID {
31 CBLOCK_DESERIALIZE=0,
32 CTRANSACTION_DESERIALIZE,
33 CBLOCKLOCATOR_DESERIALIZE,
34 CBLOCKMERKLEROOT,
35 CADDRMAN_DESERIALIZE,
36 CBLOCKHEADER_DESERIALIZE,
37 CBANENTRY_DESERIALIZE,
38 CTXUNDO_DESERIALIZE,
39 CBLOCKUNDO_DESERIALIZE,
40 CCOINS_DESERIALIZE,
41 CNETADDR_DESERIALIZE,
42 CSERVICE_DESERIALIZE,
43 CMESSAGEHEADER_DESERIALIZE,
44 CADDRESS_DESERIALIZE,
45 CINV_DESERIALIZE,
46 CBLOOMFILTER_DESERIALIZE,
47 CDISKBLOCKINDEX_DESERIALIZE,
48 CTXOUTCOMPRESSOR_DESERIALIZE,
49 BLOCKTRANSACTIONS_DESERIALIZE,
50 BLOCKTRANSACTIONSREQUEST_DESERIALIZE,
51 TEST_ID_END
54 bool read_stdin(std::vector<uint8_t> &data) {
55 uint8_t buffer[1024];
56 ssize_t length=0;
57 while((length = read(STDIN_FILENO, buffer, 1024)) > 0) {
58 data.insert(data.end(), buffer, buffer+length);
60 if (data.size() > (1<<20)) return false;
62 return length==0;
65 int test_one_input(std::vector<uint8_t> buffer) {
66 if (buffer.size() < sizeof(uint32_t)) return 0;
68 uint32_t test_id = 0xffffffff;
69 memcpy(&test_id, buffer.data(), sizeof(uint32_t));
70 buffer.erase(buffer.begin(), buffer.begin() + sizeof(uint32_t));
72 if (test_id >= TEST_ID_END) return 0;
74 CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
75 try {
76 int nVersion;
77 ds >> nVersion;
78 ds.SetVersion(nVersion);
79 } catch (const std::ios_base::failure& e) {
80 return 0;
83 switch(test_id) {
84 case CBLOCK_DESERIALIZE:
86 try
88 CBlock block;
89 ds >> block;
90 } catch (const std::ios_base::failure& e) {return 0;}
91 break;
93 case CTRANSACTION_DESERIALIZE:
95 try
97 CTransaction tx(deserialize, ds);
98 } catch (const std::ios_base::failure& e) {return 0;}
99 break;
101 case CBLOCKLOCATOR_DESERIALIZE:
105 CBlockLocator bl;
106 ds >> bl;
107 } catch (const std::ios_base::failure& e) {return 0;}
108 break;
110 case CBLOCKMERKLEROOT:
114 CBlock block;
115 ds >> block;
116 bool mutated;
117 BlockMerkleRoot(block, &mutated);
118 } catch (const std::ios_base::failure& e) {return 0;}
119 break;
121 case CADDRMAN_DESERIALIZE:
125 CAddrMan am;
126 ds >> am;
127 } catch (const std::ios_base::failure& e) {return 0;}
128 break;
130 case CBLOCKHEADER_DESERIALIZE:
134 CBlockHeader bh;
135 ds >> bh;
136 } catch (const std::ios_base::failure& e) {return 0;}
137 break;
139 case CBANENTRY_DESERIALIZE:
143 CBanEntry be;
144 ds >> be;
145 } catch (const std::ios_base::failure& e) {return 0;}
146 break;
148 case CTXUNDO_DESERIALIZE:
152 CTxUndo tu;
153 ds >> tu;
154 } catch (const std::ios_base::failure& e) {return 0;}
155 break;
157 case CBLOCKUNDO_DESERIALIZE:
161 CBlockUndo bu;
162 ds >> bu;
163 } catch (const std::ios_base::failure& e) {return 0;}
164 break;
166 case CCOINS_DESERIALIZE:
170 Coin coin;
171 ds >> coin;
172 } catch (const std::ios_base::failure& e) {return 0;}
173 break;
175 case CNETADDR_DESERIALIZE:
179 CNetAddr na;
180 ds >> na;
181 } catch (const std::ios_base::failure& e) {return 0;}
182 break;
184 case CSERVICE_DESERIALIZE:
188 CService s;
189 ds >> s;
190 } catch (const std::ios_base::failure& e) {return 0;}
191 break;
193 case CMESSAGEHEADER_DESERIALIZE:
195 CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
198 CMessageHeader mh(pchMessageStart);
199 ds >> mh;
200 if (!mh.IsValid(pchMessageStart)) {return 0;}
201 } catch (const std::ios_base::failure& e) {return 0;}
202 break;
204 case CADDRESS_DESERIALIZE:
208 CAddress a;
209 ds >> a;
210 } catch (const std::ios_base::failure& e) {return 0;}
211 break;
213 case CINV_DESERIALIZE:
217 CInv i;
218 ds >> i;
219 } catch (const std::ios_base::failure& e) {return 0;}
220 break;
222 case CBLOOMFILTER_DESERIALIZE:
226 CBloomFilter bf;
227 ds >> bf;
228 } catch (const std::ios_base::failure& e) {return 0;}
229 break;
231 case CDISKBLOCKINDEX_DESERIALIZE:
235 CDiskBlockIndex dbi;
236 ds >> dbi;
237 } catch (const std::ios_base::failure& e) {return 0;}
238 break;
240 case CTXOUTCOMPRESSOR_DESERIALIZE:
242 CTxOut to;
243 CTxOutCompressor toc(to);
246 ds >> toc;
247 } catch (const std::ios_base::failure& e) {return 0;}
249 break;
251 case BLOCKTRANSACTIONS_DESERIALIZE:
255 BlockTransactions bt;
256 ds >> bt;
257 } catch (const std::ios_base::failure& e) {return 0;}
259 break;
261 case BLOCKTRANSACTIONSREQUEST_DESERIALIZE:
265 BlockTransactionsRequest btr;
266 ds >> btr;
267 } catch (const std::ios_base::failure& e) {return 0;}
269 break;
271 default:
272 return 0;
274 return 0;
277 static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
278 void initialize() {
279 globalVerifyHandle = std::unique_ptr<ECCVerifyHandle>(new ECCVerifyHandle());
282 // This function is used by libFuzzer
283 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
284 test_one_input(std::vector<uint8_t>(data, data + size));
285 return 0;
288 // This function is used by libFuzzer
289 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
290 initialize();
291 return 0;
294 // Disabled under WIN32 due to clash with Cygwin's WinMain.
295 #ifndef WIN32
296 // Declare main(...) "weak" to allow for libFuzzer linking. libFuzzer provides
297 // the main(...) function.
298 __attribute__((weak))
299 #endif
300 int main(int argc, char **argv)
302 initialize();
303 #ifdef __AFL_INIT
304 // Enable AFL deferred forkserver mode. Requires compilation using
305 // afl-clang-fast++. See fuzzing.md for details.
306 __AFL_INIT();
307 #endif
309 #ifdef __AFL_LOOP
310 // Enable AFL persistent mode. Requires compilation using afl-clang-fast++.
311 // See fuzzing.md for details.
312 int ret = 0;
313 while (__AFL_LOOP(1000)) {
314 std::vector<uint8_t> buffer;
315 if (!read_stdin(buffer)) {
316 continue;
318 ret = test_one_input(buffer);
320 return ret;
321 #else
322 std::vector<uint8_t> buffer;
323 if (!read_stdin(buffer)) {
324 return 0;
326 return test_one_input(buffer);
327 #endif