LCOV - code coverage report
Current view: top level - src/wallet/test/fuzz - wallet_bdb_parser.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 96.0 % 50 48
Test Date: 2025-05-10 04:08:03 Functions: 100.0 % 3 3
Branches: 70.2 % 104 73

             Branch data     Line data    Source code
       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                 :           1 : void initialize_wallet_bdb_parser()
      27                 :             : {
      28   [ +  -  +  - ]:           2 :     static auto testing_setup = MakeNoLogFileContext<TestingSetup>();
      29                 :           1 :     g_setup = testing_setup.get();
      30         [ +  - ]:           2 : }
      31                 :             : 
      32         [ +  - ]:         492 : FUZZ_TARGET(wallet_bdb_parser, .init = initialize_wallet_bdb_parser)
      33                 :             : {
      34         [ +  - ]:          96 :     const auto wallet_path = g_setup->m_args.GetDataDirNet() / "fuzzed_wallet.dat";
      35                 :             : 
      36                 :          48 :     {
      37   [ +  -  +  - ]:          48 :         AutoFile outfile{fsbridge::fopen(wallet_path, "wb")};
      38         [ +  - ]:          96 :         outfile << std::span{buffer};
      39                 :           0 :     }
      40                 :             : 
      41         [ +  - ]:          48 :     const DatabaseOptions options{};
      42                 :          48 :     DatabaseStatus status;
      43         [ +  - ]:          48 :     bilingual_str error;
      44                 :             : 
      45   [ +  -  +  - ]:          96 :     fs::path bdb_ro_dumpfile{g_setup->m_args.GetDataDirNet() / "fuzzed_dumpfile_bdb_ro.dump"};
      46   [ +  -  +  + ]:          48 :     if (fs::exists(bdb_ro_dumpfile)) { // Writing into an existing dump file will throw an exception
      47         [ +  - ]:           3 :         remove(bdb_ro_dumpfile);
      48                 :             :     }
      49   [ +  -  +  -  :         144 :     g_setup->m_args.ForceSetArg("-dumpfile", fs::PathToString(bdb_ro_dumpfile));
                   +  - ]
      50                 :             : 
      51         [ +  - ]:          48 :     auto db{MakeBerkeleyRODatabase(wallet_path, options, status, error)};
      52         [ +  + ]:          48 :     if (db) {
      53   [ +  -  -  + ]:           3 :         assert(DumpWallet(g_setup->m_args, *db, error));
      54                 :             :     } else {
      55         [ +  + ]:          45 :         if (error.original.starts_with("AutoFile::ignore: end of file") ||
      56         [ +  + ]:          44 :             error.original.starts_with("AutoFile::read: end of file") ||
      57         [ +  - ]:          33 :             error.original.starts_with("AutoFile::seek: ") ||
      58         [ +  + ]:          33 :             error.original == "Not a BDB file" ||
      59         [ +  + ]:          32 :             error.original == "Unexpected page type, should be 9 (BTree Metadata)" ||
      60         [ +  + ]:          31 :             error.original == "Unexpected database flags, should only be 0x20 (subdatabases)" ||
      61         [ +  + ]:          30 :             error.original == "Unexpected outer database root page type" ||
      62         [ +  + ]:          29 :             error.original == "Unexpected number of entries in outer database root page" ||
      63         [ +  + ]:          28 :             error.original == "Subdatabase page number has unexpected length" ||
      64         [ +  + ]:          26 :             error.original == "Unknown record type in records page" ||
      65         [ +  - ]:          25 :             error.original == "Unknown record type in internal page" ||
      66         [ +  - ]:          25 :             error.original == "Unexpected page size" ||
      67         [ +  - ]:          25 :             error.original == "Unexpected page type" ||
      68         [ +  + ]:          25 :             error.original == "Page number mismatch" ||
      69         [ +  + ]:          24 :             error.original == "Bad btree level" ||
      70         [ +  + ]:          22 :             error.original == "Bad page size" ||
      71         [ +  + ]:          19 :             error.original == "Meta page number mismatch" ||
      72         [ +  + ]:          18 :             error.original == "Data record position not in page" ||
      73         [ +  - ]:          17 :             error.original == "Internal record position not in page" ||
      74         [ +  + ]:          17 :             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   [ +  +  +  - ]:          58 :             error.original == "Records page has odd number of records" ||
      76         [ +  - ]:          13 :             error.original == "Bad overflow record page type") {
      77                 :             :             // Do nothing
      78                 :          26 :         } else if (error.original == "Subdatabase last page is greater than database last page" ||
      79         [ +  + ]:          13 :                    error.original == "Page number is greater than database last page" ||
      80         [ +  + ]:          12 :                    error.original == "Last page number could not fit in file" ||
      81         [ +  + ]:          11 :                    error.original == "Subdatabase has an unexpected name" ||
      82   [ +  -  +  + ]:          15 :                    error.original == "Unsupported BDB data file version number" ||
      83         [ -  + ]:           1 :                    error.original == "BDB builtin encryption is not supported") {
      84                 :             :         } else {
      85         [ #  # ]:           0 :             throw std::runtime_error(error.original);
      86                 :             :         }
      87                 :             :     }
      88                 :         192 : }
        

Generated by: LCOV version 2.0-1