LCOV - code coverage report
Current view: top level - src/test/fuzz/util - descriptor.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 58 58 100.0 %
Date: 2024-01-03 14:57:27 Functions: 4 4 100.0 %
Branches: 65 92 70.7 %

           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/util/descriptor.h>
       6                 :            : 
       7                 :          1 : void MockedDescriptorConverter::Init() {
       8                 :            :     // The data to use as a private key or a seed for an xprv.
       9                 :          1 :     std::array<std::byte, 32> key_data{std::byte{1}};
      10                 :            :     // Generate keys of all kinds and store them in the keys array.
      11         [ +  + ]:        257 :     for (size_t i{0}; i < TOTAL_KEYS_GENERATED; i++) {
      12                 :        256 :         key_data[31] = std::byte(i);
      13                 :            : 
      14                 :            :         // If this is a "raw" key, generate a normal privkey. Otherwise generate
      15                 :            :         // an extended one.
      16 [ +  + ][ +  + ]:        256 :         if (IdIsCompPubKey(i) || IdIsUnCompPubKey(i) || IdIsXOnlyPubKey(i) || IdIsConstPrivKey(i)) {
         [ +  + ][ +  + ]
      17                 :        172 :             CKey privkey;
      18 [ +  - ][ +  - ]:        172 :             privkey.Set(UCharCast(key_data.begin()), UCharCast(key_data.end()), !IdIsUnCompPubKey(i));
         [ +  - ][ +  - ]
      19 [ +  - ][ +  + ]:        172 :             if (IdIsCompPubKey(i) || IdIsUnCompPubKey(i)) {
         [ +  - ][ +  + ]
      20         [ +  - ]:         86 :                 CPubKey pubkey{privkey.GetPubKey()};
      21 [ +  - ][ +  - ]:         86 :                 keys_str[i] = HexStr(pubkey);
      22 [ +  - ][ +  + ]:        172 :             } else if (IdIsXOnlyPubKey(i)) {
      23 [ +  - ][ +  - ]:         43 :                 const XOnlyPubKey pubkey{privkey.GetPubKey()};
      24 [ +  - ][ +  - ]:         43 :                 keys_str[i] = HexStr(pubkey);
      25                 :         43 :             } else {
      26         [ +  - ]:         43 :                 keys_str[i] = EncodeSecret(privkey);
      27                 :            :             }
      28                 :        172 :         } else {
      29                 :         84 :             CExtKey ext_privkey;
      30 [ +  - ][ +  - ]:         84 :             ext_privkey.SetSeed(key_data);
      31 [ +  - ][ +  + ]:         84 :             if (IdIsXprv(i)) {
      32         [ +  - ]:         42 :                 keys_str[i] = EncodeExtKey(ext_privkey);
      33                 :         42 :             } else {
      34         [ +  - ]:         42 :                 const CExtPubKey ext_pubkey{ext_privkey.Neuter()};
      35         [ +  - ]:         42 :                 keys_str[i] = EncodeExtPubKey(ext_pubkey);
      36                 :            :             }
      37                 :         84 :         }
      38                 :        256 :     }
      39                 :          1 : }
      40                 :            : 
      41                 :      13279 : std::optional<uint8_t> MockedDescriptorConverter::IdxFromHex(std::string_view hex_characters) const {
      42         [ -  + ]:      13279 :     if (hex_characters.size() != 2) return {};
      43                 :      13279 :     auto idx = ParseHex(hex_characters);
      44         [ +  + ]:      13279 :     if (idx.size() != 1) return {};
      45                 :      13267 :     return idx[0];
      46                 :      13279 : }
      47                 :            : 
      48                 :        828 : std::optional<std::string> MockedDescriptorConverter::GetDescriptor(std::string_view mocked_desc) const {
      49                 :            :     // The smallest fragment would be "pk(%00)"
      50         [ +  + ]:        828 :     if (mocked_desc.size() < 7) return {};
      51                 :            : 
      52                 :            :     // The actual descriptor string to be returned.
      53                 :        826 :     std::string desc;
      54         [ +  - ]:        826 :     desc.reserve(mocked_desc.size());
      55                 :            : 
      56                 :            :     // Replace all occurrences of '%' followed by two hex characters with the corresponding key.
      57         [ +  + ]:     387141 :     for (size_t i = 0; i < mocked_desc.size();) {
      58         [ +  + ]:     386329 :         if (mocked_desc[i] == '%') {
      59         [ +  + ]:      13281 :             if (i + 3 >= mocked_desc.size()) return {};
      60 [ +  - ][ +  - ]:      13279 :             if (const auto idx = IdxFromHex(mocked_desc.substr(i + 1, 2))) {
                 [ +  + ]
      61         [ +  - ]:      13267 :                 desc += keys_str[*idx];
      62                 :      13267 :                 i += 3;
      63                 :      13267 :             } else {
      64                 :         12 :                 return {};
      65                 :            :             }
      66                 :      13267 :         } else {
      67         [ +  - ]:     373048 :             desc += mocked_desc[i++];
      68                 :            :         }
      69                 :            :     }
      70                 :            : 
      71                 :        812 :     return desc;
      72                 :        828 : }
      73                 :            : 
      74                 :        829 : bool HasDeepDerivPath(const FuzzBufferType& buff, const int max_depth)
      75                 :            : {
      76                 :        829 :     auto depth{0};
      77         [ +  + ]:     413755 :     for (const auto& ch: buff) {
      78         [ +  + ]:     412927 :         if (ch == ',') {
      79                 :            :             // A comma is always present between two key expressions, so we use that as a delimiter.
      80                 :      55127 :             depth = 0;
      81         [ +  + ]:     412927 :         } else if (ch == '/') {
      82         [ +  + ]:       4770 :             if (++depth > max_depth) return true;
      83                 :       4769 :         }
      84                 :            :     }
      85                 :        828 :     return false;
      86                 :        829 : }

Generated by: LCOV version 1.14