Coverage Report

Created: 2026-11-12 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/upx/src/util/xspan_impl_span.h
Line
Count
Source
1
/* xspan -- a minimally invasive checked memory smart pointer
2
3
   This file is part of the UPX executable compressor.
4
5
   Copyright (C) Markus Franz Xaver Johannes Oberhumer
6
   All Rights Reserved.
7
8
   UPX and the UCL library are free software; you can redistribute them
9
   and/or modify them under the terms of the GNU General Public License as
10
   published by the Free Software Foundation; either version 2 of
11
   the License, or (at your option) any later version.
12
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program; see the file COPYING.
20
   If not, write to the Free Software Foundation, Inc.,
21
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23
   Markus F.X.J. Oberhumer
24
   <markus@oberhumer.com>
25
 */
26
27
#pragma once
28
29
XSPAN_NAMESPACE_BEGIN
30
31
/*************************************************************************
32
// Span
33
//
34
// invariants:
35
//   ptr != null, base != null
36
//   ptr is valid in base
37
**************************************************************************/
38
39
template <class T>
40
struct Span {
41
private:
42
44.4k
#define CSelf Span
43
    typedef CSelf<T> Self;
44
    // core config
45
#if __cplusplus >= 201103L
46
    static constexpr bool configRequirePtr = true;
47
    static constexpr bool configRequireBase = true;
48
#else
49
    enum { configRequirePtr = true };
50
    enum { configRequireBase = true };
51
#endif
52
53
#include "xspan_impl_common.h"
54
public:
55
    // constructors from pointers
56
    CSelf(pointer first) XSPAN_DELETED_FUNCTION;
57
    CSelf(XSPAN_DEBUG_ARGS pointer first) XSPAN_DELETED_FUNCTION;
58
59
    // constructors
60
    CSelf(const Self &other)
61
1.02M
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
62
1.02M
          size_in_bytes(other.size_in_bytes) {
63
1.02M
        assertInvariants();
64
1.02M
    }
XSpan::Span<char>::Span(XSpan::Span<char> const&)
Line
Count
Source
61
40.0k
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
62
40.0k
          size_in_bytes(other.size_in_bytes) {
63
40.0k
        assertInvariants();
64
40.0k
    }
XSpan::Span<unsigned char>::Span(XSpan::Span<unsigned char> const&)
Line
Count
Source
61
406
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
62
406
          size_in_bytes(other.size_in_bytes) {
63
406
        assertInvariants();
64
406
    }
XSpan::Span<unsigned char const>::Span(XSpan::Span<unsigned char const> const&)
Line
Count
Source
61
941k
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
62
941k
          size_in_bytes(other.size_in_bytes) {
63
941k
        assertInvariants();
64
941k
    }
XSpan::Span<LE32>::Span(XSpan::Span<LE32> const&)
Line
Count
Source
61
42.6k
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
62
42.6k
          size_in_bytes(other.size_in_bytes) {
63
42.6k
        assertInvariants();
64
42.6k
    }
Unexecuted instantiation: XSpan::Span<LE32 const>::Span(XSpan::Span<LE32 const> const&)
XSpan::Span<PeFile::import_desc>::Span(XSpan::Span<PeFile::import_desc> const&)
Line
Count
Source
61
301
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
62
301
          size_in_bytes(other.size_in_bytes) {
63
301
        assertInvariants();
64
301
    }
65
    CSelf(XSPAN_DEBUG_ARGS const Self &other)
66
113k
        : XSPAN_DEBUG_IMPL ptr(other.ensurePtr()), base(other.ensureBase()),
67
113k
          size_in_bytes(other.size_in_bytes) {
68
113k
        assertInvariants();
69
113k
    }
XSpan::Span<unsigned short>::Span(XSpan::XSpanDebugFile const&, XSpan::Span<unsigned short> const&)
Line
Count
Source
66
80.1k
        : XSPAN_DEBUG_IMPL ptr(other.ensurePtr()), base(other.ensureBase()),
67
80.1k
          size_in_bytes(other.size_in_bytes) {
68
80.1k
        assertInvariants();
69
80.1k
    }
Unexecuted instantiation: XSpan::Span<unsigned char>::Span(XSpan::XSpanDebugFile const&, XSpan::Span<unsigned char> const&)
XSpan::Span<unsigned char const>::Span(XSpan::XSpanDebugFile const&, XSpan::Span<unsigned char const> const&)
Line
Count
Source
66
33.0k
        : XSPAN_DEBUG_IMPL ptr(other.ensurePtr()), base(other.ensureBase()),
67
33.0k
          size_in_bytes(other.size_in_bytes) {
68
33.0k
        assertInvariants();
69
33.0k
    }
Unexecuted instantiation: XSpan::Span<char>::Span(XSpan::XSpanDebugFile const&, XSpan::Span<char> const&)
Unexecuted instantiation: XSpan::Span<LE32 const>::Span(XSpan::XSpanDebugFile const&, XSpan::Span<LE32 const> const&)
70
    template <class U>
71
    CSelf(const CSelf<U> &other, XSPAN_REQUIRES_CONVERTIBLE_A)
72
0
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
73
0
          size_in_bytes(other.size_in_bytes) {
74
0
        assertInvariants();
75
0
    }
76
    template <class U>
77
    CSelf(XSPAN_DEBUG_ARGS const CSelf<U> &other, XSPAN_REQUIRES_CONVERTIBLE_A)
78
        : XSPAN_DEBUG_IMPL ptr(other.ensurePtr()), base(other.ensureBase()),
79
          size_in_bytes(other.size_in_bytes) {
80
        assertInvariants();
81
    }
82
83
    // constructors from Span friends
84
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
85
    template <class U>
86
    CSelf(const PtrOrSpanOrNull<U> &other, XSPAN_REQUIRES_CONVERTIBLE_A)
87
120k
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
88
120k
          size_in_bytes(other.size_in_bytes) {
89
120k
        assertInvariants();
90
120k
    }
XSpan::Span<int>::Span<int>(XSpan::PtrOrSpanOrNull<int> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<int, int>::value, XSpan::XSpanInternalDummyArg>::type)
Line
Count
Source
87
80.1k
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
88
80.1k
          size_in_bytes(other.size_in_bytes) {
89
80.1k
        assertInvariants();
90
80.1k
    }
XSpan::Span<unsigned char const>::Span<unsigned char const>(XSpan::PtrOrSpanOrNull<unsigned char const> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<unsigned char const, unsigned char const>::value, XSpan::XSpanInternalDummyArg>::type)
Line
Count
Source
87
40.0k
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
88
40.0k
          size_in_bytes(other.size_in_bytes) {
89
40.0k
        assertInvariants();
90
40.0k
    }
XSpan::Span<PeFile::Reloc::BaseReloc>::Span<PeFile::Reloc::BaseReloc>(XSpan::PtrOrSpanOrNull<PeFile::Reloc::BaseReloc> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<PeFile::Reloc::BaseReloc, PeFile::Reloc::BaseReloc>::value, XSpan::XSpanInternalDummyArg>::type)
Line
Count
Source
87
424
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
88
424
          size_in_bytes(other.size_in_bytes) {
89
424
        assertInvariants();
90
424
    }
Unexecuted instantiation: XSpan::Span<unsigned char>::Span<unsigned char>(XSpan::PtrOrSpanOrNull<unsigned char> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<unsigned char, unsigned char>::value, XSpan::XSpanInternalDummyArg>::type)
91
    template <class U>
92
    CSelf(XSPAN_DEBUG_ARGS const PtrOrSpanOrNull<U> &other, XSPAN_REQUIRES_CONVERTIBLE_A)
93
0
        : XSPAN_DEBUG_IMPL ptr(other.ensurePtr()), base(other.ensureBase()),
94
0
          size_in_bytes(other.size_in_bytes) {
95
0
        assertInvariants();
96
0
    }
Unexecuted instantiation: XSpan::Span<unsigned char const>::Span<unsigned char>(XSpan::XSpanDebugFile const&, XSpan::PtrOrSpanOrNull<unsigned char> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<unsigned char, unsigned char const>::value, XSpan::XSpanInternalDummyArg>::type)
Unexecuted instantiation: XSpan::Span<unsigned char>::Span<unsigned char>(XSpan::XSpanDebugFile const&, XSpan::PtrOrSpanOrNull<unsigned char> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<unsigned char, unsigned char>::value, XSpan::XSpanInternalDummyArg>::type)
97
    template <class U>
98
    CSelf(const PtrOrSpan<U> &other, XSPAN_REQUIRES_CONVERTIBLE_A)
99
120k
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
100
120k
          size_in_bytes(other.size_in_bytes) {
101
120k
        assertInvariants();
102
120k
    }
XSpan::Span<int>::Span<int>(XSpan::PtrOrSpan<int> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<int, int>::value, XSpan::XSpanInternalDummyArg>::type)
Line
Count
Source
99
80.1k
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
100
80.1k
          size_in_bytes(other.size_in_bytes) {
101
80.1k
        assertInvariants();
102
80.1k
    }
XSpan::Span<unsigned char const>::Span<unsigned char const>(XSpan::PtrOrSpan<unsigned char const> const&, std::__1::enable_if<XSpan::XSpan_is_convertible<unsigned char const, unsigned char const>::value, XSpan::XSpanInternalDummyArg>::type)
Line
Count
Source
99
40.0k
        : XSPAN_DEBUG_OTHER ptr(other.ensurePtr()), base(other.ensureBase()),
100
40.0k
          size_in_bytes(other.size_in_bytes) {
101
40.0k
        assertInvariants();
102
40.0k
    }
103
    template <class U>
104
    CSelf(XSPAN_DEBUG_ARGS const PtrOrSpan<U> &other, XSPAN_REQUIRES_CONVERTIBLE_A)
105
        : XSPAN_DEBUG_IMPL ptr(other.ensurePtr()), base(other.ensureBase()),
106
          size_in_bytes(other.size_in_bytes) {
107
        assertInvariants();
108
    }
109
#endif
110
111
    // assignment from Span friends
112
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
113
    // TODO: use Unchecked to avoid double checks in both constructor and assignment
114
    template <class U>
115
    XSPAN_REQUIRES_CONVERTIBLE_R(Self &)
116
0
    operator=(const PtrOrSpanOrNull<U> &other) {
117
0
        if (other.base == nullptr)
118
0
            return assign(Self(other.ptr, size_in_bytes, base));
119
0
        return assign(Self(other.ptr, other.size_in_bytes, other.base));
120
0
    }
121
    template <class U>
122
    XSPAN_REQUIRES_CONVERTIBLE_R(Self &)
123
    operator=(const PtrOrSpan<U> &other) {
124
        if (other.base == nullptr)
125
            return assign(Self(other.ptr, size_in_bytes, base));
126
        return assign(Self(other.ptr, other.size_in_bytes, other.base));
127
    }
128
#endif
129
130
    // nullptr
131
    CSelf(std::nullptr_t) XSPAN_DELETED_FUNCTION;
132
    CSelf(std::nullptr_t, XSpanCount, const void *) XSPAN_DELETED_FUNCTION;
133
    CSelf(std::nullptr_t, XSpanSizeInBytes, const void *) XSPAN_DELETED_FUNCTION;
134
    CSelf(std::nullptr_t, size_type, const void *) XSPAN_DELETED_FUNCTION;
135
    CSelf(XSPAN_DEBUG_ARGS std::nullptr_t) XSPAN_DELETED_FUNCTION;
136
    CSelf(XSPAN_DEBUG_ARGS std::nullptr_t, XSpanCount, const void *) XSPAN_DELETED_FUNCTION;
137
    CSelf(XSPAN_DEBUG_ARGS std::nullptr_t, XSpanSizeInBytes, const void *) XSPAN_DELETED_FUNCTION;
138
    CSelf(XSPAN_DEBUG_ARGS std::nullptr_t, size_type, const void *) XSPAN_DELETED_FUNCTION;
139
    Self &operator=(std::nullptr_t) XSPAN_DELETED_FUNCTION;
140
#if 0
141
    // don't enable, this prevents generic usage
142
    bool operator==(std::nullptr_t) const XSPAN_DELETED_FUNCTION;
143
    bool operator!=(std::nullptr_t) const XSPAN_DELETED_FUNCTION;
144
#else
145
    bool operator==(std::nullptr_t) const {
146
        assertInvariants();
147
        return false;
148
    }
149
40.0k
    bool operator!=(std::nullptr_t) const {
150
40.0k
        assertInvariants();
151
40.0k
        return true;
152
40.0k
    }
153
#endif
154
#undef CSelf
155
};
156
157
// raw_bytes overload
158
template <class T>
159
270k
inline typename Span<T>::pointer raw_bytes(const Span<T> &a, size_t size_in_bytes) {
160
270k
    return a.raw_bytes(size_in_bytes);
161
270k
}
XSpan::Span<char>::pointer XSpan::raw_bytes<char>(XSpan::Span<char> const&, unsigned long)
Line
Count
Source
159
160k
inline typename Span<T>::pointer raw_bytes(const Span<T> &a, size_t size_in_bytes) {
160
160k
    return a.raw_bytes(size_in_bytes);
161
160k
}
XSpan::Span<unsigned char>::pointer XSpan::raw_bytes<unsigned char>(XSpan::Span<unsigned char> const&, unsigned long)
Line
Count
Source
159
12.0k
inline typename Span<T>::pointer raw_bytes(const Span<T> &a, size_t size_in_bytes) {
160
12.0k
    return a.raw_bytes(size_in_bytes);
161
12.0k
}
XSpan::Span<unsigned char const>::pointer XSpan::raw_bytes<unsigned char const>(XSpan::Span<unsigned char const> const&, unsigned long)
Line
Count
Source
159
98.4k
inline typename Span<T>::pointer raw_bytes(const Span<T> &a, size_t size_in_bytes) {
160
98.4k
    return a.raw_bytes(size_in_bytes);
161
98.4k
}
162
template <class T>
163
inline typename Span<T>::pointer raw_index_bytes(const Span<T> &a, size_t index,
164
160k
                                                 size_t size_in_bytes) {
165
160k
    typedef typename Span<T>::element_type element_type;
166
160k
    return a.raw_bytes(mem_size(sizeof(element_type), index, size_in_bytes)) + index;
167
160k
}
168
169
/*************************************************************************
170
//
171
**************************************************************************/
172
173
XSPAN_NAMESPACE_END
174
175
#if !XSPAN_CONFIG_ENABLE_IMPLICIT_CONVERSION || 1
176
177
#define C XSPAN_NS(Span)
178
#define D XSPAN_NS(PtrOrSpanOrNull)
179
#define E XSPAN_NS(PtrOrSpan)
180
#include "xspan_fwd.h"
181
#undef C
182
#undef D
183
#undef E
184
185
#endif
186
187
/* vim:set ts=4 sw=4 et: */