Bitcoin Core Fuzz Coverage Report for wallet_tx_can_be_bumped

Coverage Report

Created: 2025-11-19 11:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/Users/brunogarcia/projects/bitcoin-core-dev/src/span.h
Line
Count
Source
1
// Copyright (c) 2018-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
#ifndef BITCOIN_SPAN_H
6
#define BITCOIN_SPAN_H
7
8
#include <cassert>
9
#include <cstddef>
10
#include <span>
11
#include <type_traits>
12
#include <utility>
13
14
/** A span is an object that can refer to a contiguous sequence of objects.
15
 *
16
 * Things to be aware of when writing code that deals with spans:
17
 *
18
 * - Similar to references themselves, spans are subject to reference lifetime
19
 *   issues. The user is responsible for making sure the objects pointed to by
20
 *   a span live as long as the span is used. For example:
21
 *
22
 *       std::vector<int> vec{1,2,3,4};
23
 *       std::span<int> sp(vec);
24
 *       vec.push_back(5);
25
 *       printf("%i\n", sp.front()); // UB!
26
 *
27
 *   may exhibit undefined behavior, as increasing the size of a vector may
28
 *   invalidate references.
29
 *
30
 * - One particular pitfall is that spans can be constructed from temporaries,
31
 *   but this is unsafe when the span is stored in a variable, outliving the
32
 *   temporary. For example, this will compile, but exhibits undefined behavior:
33
 *
34
 *       std::span<const int> sp(std::vector<int>{1, 2, 3});
35
 *       printf("%i\n", sp.front()); // UB!
36
 *
37
 *   The lifetime of the vector ends when the statement it is created in ends.
38
 *   Thus the span is left with a dangling reference, and using it is undefined.
39
 *
40
 * - Due to spans automatic creation from range-like objects (arrays, and data
41
 *   types that expose a data() and size() member function), functions that
42
 *   accept a span as input parameter can be called with any compatible
43
 *   range-like object. For example, this works:
44
 *
45
 *       void Foo(std::span<const int> arg);
46
 *
47
 *       Foo(std::vector<int>{1, 2, 3}); // Works
48
 *
49
 *   This is very useful in cases where a function truly does not care about the
50
 *   container, and only about having exactly a range of elements. However it
51
 *   may also be surprising to see automatic conversions in this case.
52
 *
53
 *   When a function accepts a span with a mutable element type, it will not
54
 *   accept temporaries; only variables or other references. For example:
55
 *
56
 *       void FooMut(std::span<int> arg);
57
 *
58
 *       FooMut(std::vector<int>{1, 2, 3}); // Does not compile
59
 *       std::vector<int> baz{1, 2, 3};
60
 *       FooMut(baz); // Works
61
 *
62
 *   This is similar to how functions that take (non-const) lvalue references
63
 *   as input cannot accept temporaries. This does not work either:
64
 *
65
 *       void FooVec(std::vector<int>& arg);
66
 *       FooVec(std::vector<int>{1, 2, 3}); // Does not compile
67
 *
68
 *   The idea is that if a function accepts a mutable reference, a meaningful
69
 *   result will be present in that variable after the call. Passing a temporary
70
 *   is useless in that context.
71
 */
72
73
/** Pop the last element off a span, and return a reference to that element. */
74
template <typename T>
75
T& SpanPopBack(std::span<T>& span)
76
0
{
77
0
    size_t size = span.size();
78
0
    T& back = span.back();
79
0
    span = span.first(size - 1);
80
0
    return back;
81
0
}
Unexecuted instantiation: std::__1::vector<unsigned char, std::__1::allocator<unsigned char>> const& SpanPopBack<std::__1::vector<unsigned char, std::__1::allocator<unsigned char>> const>(std::__1::span<std::__1::vector<unsigned char, std::__1::allocator<unsigned char>> const, 18446744073709551615ul>&)
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const& SpanPopBack<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const>(std::__1::span<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const, 18446744073709551615ul>&)
Unexecuted instantiation: unsigned char const& SpanPopBack<unsigned char const>(std::__1::span<unsigned char const, 18446744073709551615ul>&)
82
83
template <typename V>
84
auto MakeByteSpan(const V& v) noexcept
85
1.22M
{
86
1.22M
    return std::as_bytes(std::span{v});
87
1.22M
}
auto MakeByteSpan<prevector<36u, unsigned char, unsigned int, int>>(prevector<36u, unsigned char, unsigned int, int> const&)
Line
Count
Source
85
114k
{
86
114k
    return std::as_bytes(std::span{v});
87
114k
}
auto MakeByteSpan<std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char>> const&)
Line
Count
Source
85
97.6k
{
86
97.6k
    return std::as_bytes(std::span{v});
87
97.6k
}
auto MakeByteSpan<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&)
Line
Count
Source
85
779k
{
86
779k
    return std::as_bytes(std::span{v});
87
779k
}
Unexecuted instantiation: auto MakeByteSpan<unsigned char [4]>(unsigned char const (&) [4])
Unexecuted instantiation: auto MakeByteSpan<unsigned char [5]>(unsigned char const (&) [5])
Unexecuted instantiation: auto MakeByteSpan<unsigned char [78]>(unsigned char const (&) [78])
Unexecuted instantiation: auto MakeByteSpan<prevector<16u, unsigned char, unsigned int, int>>(prevector<16u, unsigned char, unsigned int, int> const&)
Unexecuted instantiation: auto MakeByteSpan<unsigned char [16]>(unsigned char const (&) [16])
Unexecuted instantiation: auto MakeByteSpan<std::__1::array<unsigned char, 4ul>>(std::__1::array<unsigned char, 4ul> const&)
Unexecuted instantiation: auto MakeByteSpan<char [12]>(char const (&) [12])
Unexecuted instantiation: auto MakeByteSpan<std::__1::array<unsigned char, 5ul>>(std::__1::array<unsigned char, 5ul> const&)
auto MakeByteSpan<uint256>(uint256 const&)
Line
Count
Source
85
153k
{
86
153k
    return std::as_bytes(std::span{v});
87
153k
}
auto MakeByteSpan<std::__1::vector<unsigned char, secure_allocator<unsigned char>>>(std::__1::vector<unsigned char, secure_allocator<unsigned char>> const&)
Line
Count
Source
85
79.3k
{
86
79.3k
    return std::as_bytes(std::span{v});
87
79.3k
}
Unexecuted instantiation: auto MakeByteSpan<leveldb::Slice>(leveldb::Slice const&)
Unexecuted instantiation: auto MakeByteSpan<std::__1::vector<std::byte, std::__1::allocator<std::byte>>>(std::__1::vector<std::byte, std::__1::allocator<std::byte>> const&)
Unexecuted instantiation: auto MakeByteSpan<std::__1::array<std::byte, 168ul>>(std::__1::array<std::byte, 168ul> const&)
Unexecuted instantiation: auto MakeByteSpan<std::__1::array<std::byte, 8ul>>(std::__1::array<std::byte, 8ul> const&)
Unexecuted instantiation: auto MakeByteSpan<unsigned char [384]>(unsigned char const (&) [384])
88
template <typename V>
89
auto MakeWritableByteSpan(V&& v) noexcept
90
25.2k
{
91
25.2k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
25.2k
}
Unexecuted instantiation: auto MakeWritableByteSpan<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&)
Unexecuted instantiation: auto MakeWritableByteSpan<uint256&>(uint256&)
Unexecuted instantiation: auto MakeWritableByteSpan<std::__1::vector<std::byte, std::__1::allocator<std::byte>>&>(std::__1::vector<std::byte, std::__1::allocator<std::byte>>&)
auto MakeWritableByteSpan<std::__1::array<unsigned char, 32ul>&>(std::__1::array<unsigned char, 32ul>&)
Line
Count
Source
90
25.2k
{
91
25.2k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
25.2k
}
Unexecuted instantiation: auto MakeWritableByteSpan<std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>&>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>&)
Unexecuted instantiation: auto MakeWritableByteSpan<unsigned char (&) [16]>(unsigned char (&) [16])
Unexecuted instantiation: auto MakeWritableByteSpan<unsigned char (&) [4]>(unsigned char (&) [4])
Unexecuted instantiation: auto MakeWritableByteSpan<unsigned char (&) [5]>(unsigned char (&) [5])
Unexecuted instantiation: auto MakeWritableByteSpan<std::__1::array<unsigned char, 4ul>&>(std::__1::array<unsigned char, 4ul>&)
Unexecuted instantiation: auto MakeWritableByteSpan<char (&) [12]>(char (&) [12])
Unexecuted instantiation: auto MakeWritableByteSpan<std::__1::array<unsigned char, 5ul>&>(std::__1::array<unsigned char, 5ul>&)
Unexecuted instantiation: auto MakeWritableByteSpan<std::__1::array<unsigned char, 20ul>&>(std::__1::array<unsigned char, 20ul>&)
Unexecuted instantiation: auto MakeWritableByteSpan<std::__1::array<std::byte, 20ul>&>(std::__1::array<std::byte, 20ul>&)
Unexecuted instantiation: auto MakeWritableByteSpan<char (&) [368]>(char (&) [368])
Unexecuted instantiation: auto MakeWritableByteSpan<unsigned char (&) [20]>(unsigned char (&) [20])
Unexecuted instantiation: auto MakeWritableByteSpan<std::__1::array<std::byte, 8ul>&>(std::__1::array<std::byte, 8ul>&)
Unexecuted instantiation: auto MakeWritableByteSpan<unsigned char (&) [384]>(unsigned char (&) [384])
93
94
// Helper functions to safely cast basic byte pointers to unsigned char pointers.
95
0
inline unsigned char* UCharCast(char* c) { return reinterpret_cast<unsigned char*>(c); }
96
158k
inline unsigned char* UCharCast(unsigned char* c) { return c; }
97
0
inline unsigned char* UCharCast(signed char* c) { return reinterpret_cast<unsigned char*>(c); }
98
0
inline unsigned char* UCharCast(std::byte* c) { return reinterpret_cast<unsigned char*>(c); }
99
0
inline const unsigned char* UCharCast(const char* c) { return reinterpret_cast<const unsigned char*>(c); }
100
1.57M
inline const unsigned char* UCharCast(const unsigned char* c) { return c; }
101
0
inline const unsigned char* UCharCast(const signed char* c) { return reinterpret_cast<const unsigned char*>(c); }
102
2.00M
inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast<const unsigned char*>(c); }
103
// Helper concept for the basic byte types.
104
template <typename B>
105
concept BasicByte = requires { UCharCast(std::span<B>{}.data()); };
106
107
// Helper function to safely convert a span to a span<[const] unsigned char>.
108
1.65M
template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; }
Unexecuted instantiation: auto UCharSpanCast<char const, 18446744073709551615ul>(std::__1::span<char const, 18446744073709551615ul>)
Unexecuted instantiation: auto UCharSpanCast<std::byte const, 18446744073709551615ul>(std::__1::span<std::byte const, 18446744073709551615ul>)
auto UCharSpanCast<unsigned char const, 18446744073709551615ul>(std::__1::span<unsigned char const, 18446744073709551615ul>)
Line
Count
Source
108
1.49M
template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; }
auto UCharSpanCast<unsigned char, 18446744073709551615ul>(std::__1::span<unsigned char, 18446744073709551615ul>)
Line
Count
Source
108
158k
template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; }
Unexecuted instantiation: auto UCharSpanCast<unsigned char const, 8ul>(std::__1::span<unsigned char const, 8ul>)
109
110
/** Like the std::span constructor, but for (const) unsigned char member types only. Only works for (un)signed char containers. */
111
1.65M
template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
Unexecuted instantiation: decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<std::__1::span<char const, 18446744073709551615ul>>(std::__1::span<char const, 18446744073709551615ul> const&)
Unexecuted instantiation: decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<std::__1::span<std::byte const, 18446744073709551615ul>>(std::__1::span<std::byte const, 18446744073709551615ul> const&)
Unexecuted instantiation: decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<std::__1::basic_string_view<char, std::__1::char_traits<char>>>(std::__1::basic_string_view<char, std::__1::char_traits<char>> const&)
decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<std::__1::span<unsigned char const, 18446744073709551615ul>>(std::__1::span<unsigned char const, 18446744073709551615ul> const&)
Line
Count
Source
111
1.10M
template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
Unexecuted instantiation: decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&)
decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char>> const&)
Line
Count
Source
111
343k
template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
Unexecuted instantiation: decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<uint256>(uint256 const&)
Unexecuted instantiation: decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<XOnlyPubKey>(XOnlyPubKey const&)
Unexecuted instantiation: decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<CPubKey>(CPubKey const&)
decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<CScript>(CScript const&)
Line
Count
Source
111
49.2k
template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<std::__1::span<unsigned char, 18446744073709551615ul>>(std::__1::span<unsigned char, 18446744073709551615ul> const&)
Line
Count
Source
111
158k
template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
Unexecuted instantiation: decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<DataStream>(DataStream const&)
Unexecuted instantiation: decltype(UCharSpanCast(std::__1::span{fp})) MakeUCharSpan<unsigned char [8]>(unsigned char const (&) [8])
112
template <typename V> constexpr auto MakeWritableUCharSpan(V&& v) -> decltype(UCharSpanCast(std::span{std::forward<V>(v)})) { return UCharSpanCast(std::span{std::forward<V>(v)}); }
113
114
#endif // BITCOIN_SPAN_H