Bitcoin Core  31.0.0
P2P Digital Currency
wallet_bdb_parser.cpp
Go to the documentation of this file.
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 
6 #include <test/fuzz/fuzz.h>
7 #include <test/fuzz/util.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 
21 
22 namespace {
24 } // namespace
25 
27 {
28  static auto testing_setup = MakeNoLogFileContext<TestingSetup>();
29  g_setup = testing_setup.get();
30 }
31 
33 {
34  const auto wallet_path = g_setup->m_args.GetDataDirNet() / "fuzzed_wallet.dat";
35 
36  {
37  AutoFile outfile{fsbridge::fopen(wallet_path, "wb")};
38  outfile << std::span{buffer};
39  assert(outfile.fclose() == 0);
40  }
41 
42  const DatabaseOptions options{};
43  DatabaseStatus status;
44  bilingual_str error;
45 
46  fs::path bdb_ro_dumpfile{g_setup->m_args.GetDataDirNet() / "fuzzed_dumpfile_bdb_ro.dump"};
47  if (fs::exists(bdb_ro_dumpfile)) { // Writing into an existing dump file will throw an exception
48  remove(bdb_ro_dumpfile);
49  }
50  g_setup->m_args.ForceSetArg("-dumpfile", fs::PathToString(bdb_ro_dumpfile));
51 
52  auto db{MakeBerkeleyRODatabase(wallet_path, options, status, error)};
53  if (db) {
54  assert(DumpWallet(g_setup->m_args, *db, error));
55  } else {
56  if (error.original.starts_with("AutoFile::ignore: end of file") ||
57  error.original.starts_with("AutoFile::read: end of file") ||
58  error.original.starts_with("AutoFile::seek: ") ||
59  error.original == "Not a BDB file" ||
60  error.original == "Unexpected page type, should be 9 (BTree Metadata)" ||
61  error.original == "Unexpected database flags, should only be 0x20 (subdatabases)" ||
62  error.original == "Unexpected outer database root page type" ||
63  error.original == "Unexpected number of entries in outer database root page" ||
64  error.original == "Subdatabase page number has unexpected length" ||
65  error.original == "Unknown record type in records page" ||
66  error.original == "Unknown record type in internal page" ||
67  error.original == "Unexpected page size" ||
68  error.original == "Unexpected page type" ||
69  error.original == "Page number mismatch" ||
70  error.original == "Bad btree level" ||
71  error.original == "Bad page size" ||
72  error.original == "Meta page number mismatch" ||
73  error.original == "Data record position not in page" ||
74  error.original == "Internal record position not in page" ||
75  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" ||
76  error.original == "Records page has odd number of records" ||
77  error.original == "Bad overflow record page type") {
78  // Do nothing
79  } else if (error.original == "Subdatabase last page is greater than database last page" ||
80  error.original == "Page number is greater than database last page" ||
81  error.original == "Last page number could not fit in file" ||
82  error.original == "Subdatabase has an unexpected name" ||
83  error.original == "Unsupported BDB data file version number" ||
84  error.original == "BDB builtin encryption is not supported") {
85  } else {
86  throw std::runtime_error(error.original);
87  }
88  }
89 }
std::unique_ptr< BerkeleyRODatabase > MakeBerkeleyRODatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Return object giving access to Berkeley Read Only database at specified path.
Definition: migrate.cpp:775
assert(!tx.IsCoinBase())
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:25
Bilingual messages:
Definition: translation.h:24
ArgsManager m_args
Test-specific arguments and settings.
Definition: setup_common.h:99
const TestingSetup * g_setup
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: args.cpp:571
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:372
FUZZ_TARGET(wallet_bdb_parser,.init=initialize_wallet_bdb_parser)
static bool exists(const path &p)
Definition: fs.h:95
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: args.h:239
bool DumpWallet(const ArgsManager &args, WalletDatabase &db, bilingual_str &error)
Definition: dump.cpp:24
DatabaseStatus
Definition: db.h:186
std::string original
Definition: translation.h:25
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:157
void initialize_wallet_bdb_parser()
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:33
Testing setup that configures a complete environment.
Definition: setup_common.h:121