LCOV - code coverage report
Current view: top level - src/test/fuzz - asmap_direct.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 100.0 % 35 35
Test Date: 2026-02-19 05:12:30 Functions: 100.0 % 3 3
Branches: 80.0 % 50 40

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2020-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 <netaddress.h>
       6                 :             : #include <util/asmap.h>
       7                 :             : #include <test/fuzz/fuzz.h>
       8                 :             : 
       9                 :             : #include <cstdint>
      10                 :             : #include <optional>
      11                 :             : #include <vector>
      12                 :             : 
      13                 :             : #include <cassert>
      14                 :             : 
      15                 :      143228 : std::vector<std::byte> BitsToBytes(std::span<const uint8_t> bits) noexcept
      16                 :             : {
      17                 :      143228 :     std::vector<std::byte> ret;
      18                 :      143228 :     uint8_t next_byte{0};
      19                 :      143228 :     int next_byte_bits{0};
      20         [ +  + ]:   136451324 :     for (uint8_t val : bits) {
      21                 :   136308096 :         next_byte |= (val & 1) << (next_byte_bits++);
      22         [ +  + ]:   136308096 :         if (next_byte_bits == 8) {
      23                 :    16975949 :             ret.push_back(std::byte(next_byte));
      24                 :    16975949 :             next_byte = 0;
      25                 :    16975949 :             next_byte_bits = 0;
      26                 :             :         }
      27                 :             :     }
      28         [ +  + ]:      143228 :     if (next_byte_bits) ret.push_back(std::byte(next_byte));
      29                 :             : 
      30                 :      143228 :     return ret;
      31                 :             : }
      32                 :             : 
      33         [ +  - ]:         858 : FUZZ_TARGET(asmap_direct)
      34                 :             : {
      35                 :             :     // Encoding: [asmap using 1 bit / byte] 0xFF [addr using 1 bit / byte]
      36                 :         404 :     std::optional<size_t> sep_pos_opt;
      37         [ +  + ]:      254261 :     for (size_t pos = 0; pos < buffer.size(); ++pos) {
      38         [ +  + ]:      253862 :         uint8_t x = buffer[pos];
      39         [ +  + ]:      253862 :         if ((x & 0xFE) == 0) continue;
      40         [ +  + ]:         403 :         if (x == 0xFF) {
      41         [ +  + ]:         399 :             if (sep_pos_opt) return;
      42                 :         398 :             sep_pos_opt = pos;
      43                 :             :         } else {
      44                 :             :             return;
      45                 :             :         }
      46                 :             :     }
      47         [ +  + ]:         399 :     if (!sep_pos_opt) return; // Needs exactly 1 separator
      48         [ +  + ]:         397 :     const size_t sep_pos{sep_pos_opt.value()};
      49         [ +  + ]:         397 :     const size_t ip_len{buffer.size() - sep_pos - 1};
      50         [ +  + ]:         397 :     if (ip_len > 128) return; // At most 128 bits in IP address
      51                 :             : 
      52                 :             :     // Checks on asmap
      53                 :         396 :     auto asmap = BitsToBytes(buffer.first(sep_pos));
      54   [ -  +  +  -  :         396 :     if (SanityCheckAsmap(asmap, ip_len)) {
                   +  + ]
      55                 :             :         // Verify that for valid asmaps, no prefix (except up to 7 zero padding bits) is valid.
      56         [ +  + ]:      142832 :         for (size_t prefix_len = sep_pos - 1; prefix_len > 0; --prefix_len) {
      57                 :      142609 :             auto prefix = BitsToBytes(buffer.first(prefix_len));
      58                 :             :             // We have to skip the prefixes of the same length as the original
      59                 :             :             // asmap, since they will contain some zero padding bits in the last
      60                 :             :             // byte.
      61   [ -  +  -  +  :      142609 :             if (prefix.size() == asmap.size()) continue;
                   +  + ]
      62   [ +  -  -  + ]:      141864 :             assert(!SanityCheckAsmap(prefix, ip_len));
      63                 :      142609 :         }
      64                 :             : 
      65                 :             :         // No address input should trigger assertions in interpreter
      66                 :         223 :         auto addr = BitsToBytes(buffer.subspan(sep_pos + 1));
      67   [ -  +  -  +  :         223 :         (void)Interpret(asmap, addr);
                   +  - ]
      68                 :         223 :     }
      69                 :         396 : }
        

Generated by: LCOV version 2.0-1