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: 98.0 % 51 50
Test Date: 2025-07-10 04:10:27 Functions: 100.0 % 3 3
Branches: 69.4 % 108 75

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

Generated by: LCOV version 2.0-1