/root/bitcoin/src/wallet/test/fuzz/wallet_bdb_parser.cpp
Line | Count | Source |
1 | | // Copyright (c) 2023-present 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 <test/fuzz/FuzzedDataProvider.h> |
6 | | #include <test/fuzz/fuzz.h> |
7 | | #include <test/fuzz/util.h> |
8 | | #include <test/util/setup_common.h> |
9 | | #include <util/fs.h> |
10 | | #include <util/time.h> |
11 | | #include <util/translation.h> |
12 | | #include <wallet/db.h> |
13 | | #include <wallet/dump.h> |
14 | | #include <wallet/migrate.h> |
15 | | |
16 | | #include <fstream> |
17 | | #include <iostream> |
18 | | |
19 | | using wallet::DatabaseOptions; |
20 | | using wallet::DatabaseStatus; |
21 | | |
22 | | namespace { |
23 | | TestingSetup* g_setup; |
24 | | } // namespace |
25 | | |
26 | | void initialize_wallet_bdb_parser() |
27 | 0 | { |
28 | 0 | static auto testing_setup = MakeNoLogFileContext<TestingSetup>(); |
29 | 0 | g_setup = testing_setup.get(); |
30 | 0 | } |
31 | | |
32 | | FUZZ_TARGET(wallet_bdb_parser, .init = initialize_wallet_bdb_parser) |
33 | 0 | { |
34 | 0 | const auto wallet_path = g_setup->m_args.GetDataDirNet() / "fuzzed_wallet.dat"; |
35 | |
|
36 | 0 | { |
37 | 0 | AutoFile outfile{fsbridge::fopen(wallet_path, "wb")}; |
38 | 0 | outfile << std::span{buffer}; |
39 | 0 | } |
40 | |
|
41 | 0 | const DatabaseOptions options{}; |
42 | 0 | DatabaseStatus status; |
43 | 0 | bilingual_str error; |
44 | |
|
45 | 0 | fs::path bdb_ro_dumpfile{g_setup->m_args.GetDataDirNet() / "fuzzed_dumpfile_bdb_ro.dump"}; |
46 | 0 | if (fs::exists(bdb_ro_dumpfile)) { // Writing into an existing dump file will throw an exception |
47 | 0 | remove(bdb_ro_dumpfile); |
48 | 0 | } |
49 | 0 | g_setup->m_args.ForceSetArg("-dumpfile", fs::PathToString(bdb_ro_dumpfile)); |
50 | |
|
51 | 0 | auto db{MakeBerkeleyRODatabase(wallet_path, options, status, error)}; |
52 | 0 | if (db) { |
53 | 0 | assert(DumpWallet(g_setup->m_args, *db, error)); |
54 | 0 | } else { |
55 | 0 | if (error.original.starts_with("AutoFile::ignore: end of file") || |
56 | 0 | error.original.starts_with("AutoFile::read: end of file") || |
57 | 0 | error.original.starts_with("AutoFile::seek: ") || |
58 | 0 | error.original == "Not a BDB file" || |
59 | 0 | error.original == "Unexpected page type, should be 9 (BTree Metadata)" || |
60 | 0 | error.original == "Unexpected database flags, should only be 0x20 (subdatabases)" || |
61 | 0 | error.original == "Unexpected outer database root page type" || |
62 | 0 | error.original == "Unexpected number of entries in outer database root page" || |
63 | 0 | error.original == "Subdatabase page number has unexpected length" || |
64 | 0 | error.original == "Unknown record type in records page" || |
65 | 0 | error.original == "Unknown record type in internal page" || |
66 | 0 | error.original == "Unexpected page size" || |
67 | 0 | error.original == "Unexpected page type" || |
68 | 0 | error.original == "Page number mismatch" || |
69 | 0 | error.original == "Bad btree level" || |
70 | 0 | error.original == "Bad page size" || |
71 | 0 | error.original == "Meta page number mismatch" || |
72 | 0 | error.original == "Data record position not in page" || |
73 | 0 | error.original == "Internal record position not in page" || |
74 | 0 | error.original == "LSNs are not reset, this database is not completely flushed. Please reopen then close the database with a version that has BDB support" || |
75 | 0 | error.original == "Records page has odd number of records" || |
76 | 0 | error.original == "Bad overflow record page type") { |
77 | | // Do nothing |
78 | 0 | } else if (error.original == "Subdatabase last page is greater than database last page" || |
79 | 0 | error.original == "Page number is greater than database last page" || |
80 | 0 | error.original == "Last page number could not fit in file" || |
81 | 0 | error.original == "Subdatabase has an unexpected name" || |
82 | 0 | error.original == "Unsupported BDB data file version number" || |
83 | 0 | error.original == "BDB builtin encryption is not supported") { |
84 | 0 | } else { |
85 | 0 | throw std::runtime_error(error.original); |
86 | 0 | } |
87 | 0 | } |
88 | 0 | } |