Coverage Report

Created: 2023-06-07 07:11

/src/boringssl/include/openssl/span.h
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (c) 2017, Google Inc.
2
 *
3
 * Permission to use, copy, modify, and/or distribute this software for any
4
 * purpose with or without fee is hereby granted, provided that the above
5
 * copyright notice and this permission notice appear in all copies.
6
 *
7
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15
#ifndef OPENSSL_HEADER_SSL_SPAN_H
16
#define OPENSSL_HEADER_SSL_SPAN_H
17
18
#include <openssl/base.h>
19
20
#if !defined(BORINGSSL_NO_CXX)
21
22
extern "C++" {
23
24
#include <stdlib.h>
25
26
#include <algorithm>
27
#include <type_traits>
28
29
BSSL_NAMESPACE_BEGIN
30
31
template <typename T>
32
class Span;
33
34
namespace internal {
35
template <typename T>
36
class SpanBase {
37
  // Put comparison operator implementations into a base class with const T, so
38
  // they can be used with any type that implicitly converts into a Span.
39
  static_assert(std::is_const<T>::value,
40
                "Span<T> must be derived from SpanBase<const T>");
41
42
0
  friend bool operator==(Span<T> lhs, Span<T> rhs) {
43
    // MSVC issues warning C4996 because std::equal is unsafe. The pragma to
44
    // suppress the warning mysteriously has no effect, hence this
45
    // implementation. See
46
    // https://msdn.microsoft.com/en-us/library/aa985974.aspx.
47
0
    if (lhs.size() != rhs.size()) {
48
0
      return false;
49
0
    }
50
0
    for (T *l = lhs.begin(), *r = rhs.begin(); l != lhs.end() && r != rhs.end();
51
0
         ++l, ++r) {
52
0
      if (*l != *r) {
53
0
        return false;
54
0
      }
55
0
    }
56
0
    return true;
57
0
  }
58
59
0
  friend bool operator!=(Span<T> lhs, Span<T> rhs) { return !(lhs == rhs); }
60
};
61
}  // namespace internal
62
63
// A Span<T> is a non-owning reference to a contiguous array of objects of type
64
// |T|. Conceptually, a Span is a simple a pointer to |T| and a count of
65
// elements accessible via that pointer. The elements referenced by the Span can
66
// be mutated if |T| is mutable.
67
//
68
// A Span can be constructed from container types implementing |data()| and
69
// |size()| methods. If |T| is constant, construction from a container type is
70
// implicit. This allows writing methods that accept data from some unspecified
71
// container type:
72
//
73
// // Foo views data referenced by v.
74
// void Foo(bssl::Span<const uint8_t> v) { ... }
75
//
76
// std::vector<uint8_t> vec;
77
// Foo(vec);
78
//
79
// For mutable Spans, conversion is explicit:
80
//
81
// // FooMutate mutates data referenced by v.
82
// void FooMutate(bssl::Span<uint8_t> v) { ... }
83
//
84
// FooMutate(bssl::Span<uint8_t>(vec));
85
//
86
// You can also use the |MakeSpan| and |MakeConstSpan| factory methods to
87
// construct Spans in order to deduce the type of the Span automatically.
88
//
89
// FooMutate(bssl::MakeSpan(vec));
90
//
91
// Note that Spans have value type sematics. They are cheap to construct and
92
// copy, and should be passed by value whenever a method would otherwise accept
93
// a reference or pointer to a container or array.
94
template <typename T>
95
class Span : private internal::SpanBase<const T> {
96
 private:
97
  static const size_t npos = static_cast<size_t>(-1);
98
99
  // Heuristically test whether C is a container type that can be converted into
100
  // a Span by checking for data() and size() member functions.
101
  //
102
  // TODO(davidben): Require C++17 support for std::is_convertible_v, etc.
103
  template <typename C>
104
  using EnableIfContainer = std::enable_if_t<
105
      std::is_convertible<decltype(std::declval<C>().data()), T *>::value &&
106
      std::is_integral<decltype(std::declval<C>().size())>::value>;
107
108
 public:
109
0
  constexpr Span() : Span(nullptr, 0) {}
Unexecuted instantiation: bssl::Span<char const*>::Span()
Unexecuted instantiation: bssl::Span<unsigned char const>::Span()
Unexecuted instantiation: bssl::Span<unsigned short const>::Span()
Unexecuted instantiation: bssl::Span<char const>::Span()
Unexecuted instantiation: bssl::Span<unsigned char>::Span()
110
10.9k
  constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {}
bssl::Span<unsigned char const>::Span(unsigned char const*, unsigned long)
Line
Count
Source
110
10.9k
  constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {}
bssl::Span<bool const>::Span(bool const*, unsigned long)
Line
Count
Source
110
4
  constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {}
Unexecuted instantiation: bssl::Span<char const*>::Span(char const**, unsigned long)
Unexecuted instantiation: bssl::Span<ssl_cipher_st const>::Span(ssl_cipher_st const*, unsigned long)
Unexecuted instantiation: bssl::Span<char const* const>::Span(char const* const*, unsigned long)
Unexecuted instantiation: bssl::Span<unsigned char>::Span(unsigned char*, unsigned long)
Unexecuted instantiation: bssl::Span<unsigned short const>::Span(unsigned short const*, unsigned long)
Unexecuted instantiation: bssl::Span<int const>::Span(int const*, unsigned long)
Unexecuted instantiation: bssl::Span<SignatureAlgorithmName const>::Span(SignatureAlgorithmName const*, unsigned long)
Unexecuted instantiation: bssl::Span<bssl::VersionInfo const>::Span(bssl::VersionInfo const*, unsigned long)
Unexecuted instantiation: bssl::Span<char const>::Span(char const*, unsigned long)
Unexecuted instantiation: bssl::Span<bssl::NamedGroup const>::Span(bssl::NamedGroup const*, unsigned long)
111
112
  template <size_t N>
113
0
  constexpr Span(T (&array)[N]) : Span(array, N) {}
Unexecuted instantiation: bssl::Span<ssl_cipher_st const>::Span<24ul>(ssl_cipher_st const (&) [24ul])
Unexecuted instantiation: bssl::Span<unsigned char const>::Span<32ul>(unsigned char const (&) [32ul])
Unexecuted instantiation: bssl::Span<char const* const>::Span<3ul>(char const* const (&) [3ul])
Unexecuted instantiation: bssl::Span<SignatureAlgorithmName const>::Span<13ul>(SignatureAlgorithmName const (&) [13ul])
Unexecuted instantiation: bssl::Span<unsigned char const>::Span<4ul>(unsigned char const (&) [4ul])
Unexecuted instantiation: bssl::Span<unsigned short const>::Span<2ul>(unsigned short const (&) [2ul])
Unexecuted instantiation: bssl::Span<unsigned short const>::Span<4ul>(unsigned short const (&) [4ul])
Unexecuted instantiation: bssl::Span<bssl::VersionInfo const>::Span<6ul>(bssl::VersionInfo const (&) [6ul])
Unexecuted instantiation: bssl::Span<char const>::Span<34ul>(char const (&) [34ul])
Unexecuted instantiation: bssl::Span<char const>::Span<20ul>(char const (&) [20ul])
Unexecuted instantiation: bssl::Span<unsigned char>::Span<8ul>(unsigned char (&) [8ul])
Unexecuted instantiation: bssl::Span<unsigned char const>::Span<1ul>(unsigned char const (&) [1ul])
Unexecuted instantiation: bssl::Span<unsigned short const>::Span<3ul>(unsigned short const (&) [3ul])
Unexecuted instantiation: bssl::Span<unsigned short const>::Span<9ul>(unsigned short const (&) [9ul])
Unexecuted instantiation: bssl::Span<unsigned char const>::Span<16ul>(unsigned char const (&) [16ul])
Unexecuted instantiation: bssl::Span<unsigned short const>::Span<12ul>(unsigned short const (&) [12ul])
Unexecuted instantiation: bssl::Span<unsigned char>::Span<32ul>(unsigned char (&) [32ul])
Unexecuted instantiation: bssl::Span<unsigned char const>::Span<8ul>(unsigned char const (&) [8ul])
Unexecuted instantiation: bssl::Span<unsigned char const>::Span<2ul>(unsigned char const (&) [2ul])
Unexecuted instantiation: bssl::Span<bssl::NamedGroup const>::Span<6ul>(bssl::NamedGroup const (&) [6ul])
114
115
  template <typename C, typename = EnableIfContainer<C>,
116
            typename = std::enable_if_t<std::is_const<T>::value, C>>
117
0
  Span(const C &container) : data_(container.data()), size_(container.size()) {}
Unexecuted instantiation: bssl::Span<char const* const>::Span<bssl::Span<char const*>, void, bssl::Span<char const*> >(bssl::Span<char const*> const&)
Unexecuted instantiation: bssl::Span<unsigned short const>::Span<bssl::Array<unsigned short>, void, bssl::Array<unsigned short> >(bssl::Array<unsigned short> const&)
Unexecuted instantiation: bssl::Span<unsigned char const>::Span<bssl::Array<unsigned char>, void, bssl::Array<unsigned char> >(bssl::Array<unsigned char> const&)
Unexecuted instantiation: bssl::Span<unsigned char const>::Span<bssl::Span<unsigned char>, void, bssl::Span<unsigned char> >(bssl::Span<unsigned char> const&)
118
119
  template <typename C, typename = EnableIfContainer<C>,
120
            typename = std::enable_if_t<!std::is_const<T>::value, C>>
121
  explicit Span(C &container)
122
      : data_(container.data()), size_(container.size()) {}
123
124
10.9k
  T *data() const { return data_; }
bssl::Span<unsigned char const>::data() const
Line
Count
Source
124
10.9k
  T *data() const { return data_; }
bssl::Span<bool const>::data() const
Line
Count
Source
124
2
  T *data() const { return data_; }
Unexecuted instantiation: bssl::Span<char const*>::data() const
Unexecuted instantiation: bssl::Span<unsigned char>::data() const
Unexecuted instantiation: bssl::Span<unsigned short const>::data() const
Unexecuted instantiation: bssl::Span<char const>::data() const
125
21.9k
  size_t size() const { return size_; }
bssl::Span<unsigned char const>::size() const
Line
Count
Source
125
21.9k
  size_t size() const { return size_; }
bssl::Span<bool const>::size() const
Line
Count
Source
125
6
  size_t size() const { return size_; }
Unexecuted instantiation: bssl::Span<char const* const>::size() const
Unexecuted instantiation: bssl::Span<ssl_cipher_st const>::size() const
Unexecuted instantiation: bssl::Span<char const*>::size() const
Unexecuted instantiation: bssl::Span<int const>::size() const
Unexecuted instantiation: bssl::Span<unsigned char>::size() const
Unexecuted instantiation: bssl::Span<unsigned short const>::size() const
Unexecuted instantiation: bssl::Span<SignatureAlgorithmName const>::size() const
Unexecuted instantiation: bssl::Span<bssl::VersionInfo const>::size() const
Unexecuted instantiation: bssl::Span<char const>::size() const
Unexecuted instantiation: bssl::Span<bssl::NamedGroup const>::size() const
126
0
  bool empty() const { return size_ == 0; }
Unexecuted instantiation: bssl::Span<char const*>::empty() const
Unexecuted instantiation: bssl::Span<unsigned char>::empty() const
Unexecuted instantiation: bssl::Span<unsigned char const>::empty() const
Unexecuted instantiation: bssl::Span<unsigned short const>::empty() const
127
128
0
  T *begin() const { return data_; }
Unexecuted instantiation: bssl::Span<unsigned char const>::begin() const
Unexecuted instantiation: bssl::Span<unsigned short const>::begin() const
129
  const T *cbegin() const { return data_; }
130
0
  T *end() const { return data_ + size_; }
Unexecuted instantiation: bssl::Span<unsigned char const>::end() const
Unexecuted instantiation: bssl::Span<unsigned short const>::end() const
131
  const T *cend() const { return end(); }
132
133
0
  T &front() const {
134
0
    if (size_ == 0) {
135
0
      abort();
136
0
    }
137
0
    return data_[0];
138
0
  }
139
0
  T &back() const {
140
0
    if (size_ == 0) {
141
0
      abort();
142
0
    }
143
0
    return data_[size_ - 1];
144
0
  }
Unexecuted instantiation: bssl::Span<unsigned char const>::back() const
Unexecuted instantiation: bssl::Span<unsigned char>::back() const
145
146
0
  T &operator[](size_t i) const {
147
0
    if (i >= size_) {
148
0
      abort();
149
0
    }
150
0
    return data_[i];
151
0
  }
Unexecuted instantiation: bssl::Span<char const* const>::operator[](unsigned long) const
Unexecuted instantiation: bssl::Span<char const*>::operator[](unsigned long) const
Unexecuted instantiation: bssl::Span<ssl_cipher_st const>::operator[](unsigned long) const
Unexecuted instantiation: bssl::Span<int const>::operator[](unsigned long) const
Unexecuted instantiation: bssl::Span<SignatureAlgorithmName const>::operator[](unsigned long) const
Unexecuted instantiation: bssl::Span<unsigned char const>::operator[](unsigned long) const
Unexecuted instantiation: bssl::Span<bssl::VersionInfo const>::operator[](unsigned long) const
Unexecuted instantiation: bssl::Span<unsigned char>::operator[](unsigned long) const
Unexecuted instantiation: bssl::Span<unsigned short const>::operator[](unsigned long) const
Unexecuted instantiation: bssl::Span<bssl::NamedGroup const>::operator[](unsigned long) const
152
  T &at(size_t i) const { return (*this)[i]; }
153
154
2
  Span subspan(size_t pos = 0, size_t len = npos) const {
155
2
    if (pos > size_) {
156
      // absl::Span throws an exception here. Note std::span and Chromium
157
      // base::span additionally forbid pos + len being out of range, with a
158
      // special case at npos/dynamic_extent, while absl::Span::subspan clips
159
      // the span. For now, we align with absl::Span in case we switch to it in
160
      // the future.
161
0
      abort();
162
0
    }
163
2
    return Span(data_ + pos, std::min(size_ - pos, len));
164
2
  }
bssl::Span<bool const>::subspan(unsigned long, unsigned long) const
Line
Count
Source
154
2
  Span subspan(size_t pos = 0, size_t len = npos) const {
155
2
    if (pos > size_) {
156
      // absl::Span throws an exception here. Note std::span and Chromium
157
      // base::span additionally forbid pos + len being out of range, with a
158
      // special case at npos/dynamic_extent, while absl::Span::subspan clips
159
      // the span. For now, we align with absl::Span in case we switch to it in
160
      // the future.
161
0
      abort();
162
0
    }
163
2
    return Span(data_ + pos, std::min(size_ - pos, len));
164
2
  }
Unexecuted instantiation: bssl::Span<char const*>::subspan(unsigned long, unsigned long) const
Unexecuted instantiation: bssl::Span<unsigned char>::subspan(unsigned long, unsigned long) const
Unexecuted instantiation: bssl::Span<unsigned char const>::subspan(unsigned long, unsigned long) const
165
166
0
  Span first(size_t len) {
167
0
    if (len > size_) {
168
0
      abort();
169
0
    }
170
0
    return Span(data_, len);
171
0
  }
172
173
0
  Span last(size_t len) {
174
0
    if (len > size_) {
175
0
      abort();
176
0
    }
177
0
    return Span(data_ + size_ - len, len);
178
0
  }
Unexecuted instantiation: bssl::Span<unsigned char>::last(unsigned long)
Unexecuted instantiation: bssl::Span<unsigned char const>::last(unsigned long)
179
180
 private:
181
  T *data_;
182
  size_t size_;
183
};
184
185
template <typename T>
186
const size_t Span<T>::npos;
187
188
template <typename T>
189
0
Span<T> MakeSpan(T *ptr, size_t size) {
190
0
  return Span<T>(ptr, size);
191
0
}
Unexecuted instantiation: bssl::Span<unsigned char> bssl::MakeSpan<unsigned char>(unsigned char*, unsigned long)
Unexecuted instantiation: bssl::Span<char const*> bssl::MakeSpan<char const*>(char const**, unsigned long)
192
193
template <typename C>
194
0
auto MakeSpan(C &c) -> decltype(MakeSpan(c.data(), c.size())) {
195
0
  return MakeSpan(c.data(), c.size());
196
0
}
197
198
template <typename T>
199
10.9k
Span<const T> MakeConstSpan(T *ptr, size_t size) {
200
10.9k
  return Span<const T>(ptr, size);
201
10.9k
}
bssl::Span<unsigned char const> bssl::MakeConstSpan<unsigned char const>(unsigned char const*, unsigned long)
Line
Count
Source
199
10.9k
Span<const T> MakeConstSpan(T *ptr, size_t size) {
200
10.9k
  return Span<const T>(ptr, size);
201
10.9k
}
Unexecuted instantiation: bssl::Span<ssl_cipher_st const> bssl::MakeConstSpan<ssl_cipher_st const>(ssl_cipher_st const*, unsigned long)
bssl::Span<bool const> bssl::MakeConstSpan<bool const>(bool const*, unsigned long)
Line
Count
Source
199
2
Span<const T> MakeConstSpan(T *ptr, size_t size) {
200
2
  return Span<const T>(ptr, size);
201
2
}
Unexecuted instantiation: bssl::Span<char const* const> bssl::MakeConstSpan<char const*>(char const**, unsigned long)
Unexecuted instantiation: bssl::Span<unsigned short const> bssl::MakeConstSpan<unsigned short const>(unsigned short const*, unsigned long)
Unexecuted instantiation: bssl::Span<int const> bssl::MakeConstSpan<int const>(int const*, unsigned long)
Unexecuted instantiation: bssl::Span<unsigned char const> bssl::MakeConstSpan<unsigned char>(unsigned char*, unsigned long)
Unexecuted instantiation: bssl::Span<char const> bssl::MakeConstSpan<char const>(char const*, unsigned long)
Unexecuted instantiation: bssl::Span<unsigned short const> bssl::MakeConstSpan<unsigned short>(unsigned short*, unsigned long)
Unexecuted instantiation: bssl::Span<bssl::NamedGroup const> bssl::MakeConstSpan<bssl::NamedGroup const>(bssl::NamedGroup const*, unsigned long)
202
203
template <typename C>
204
2
auto MakeConstSpan(const C &c) -> decltype(MakeConstSpan(c.data(), c.size())) {
205
2
  return MakeConstSpan(c.data(), c.size());
206
2
}
decltype (MakeConstSpan(({parm#1}.data)(), ({parm#1}.size)())) bssl::MakeConstSpan<bssl::Array<bool> >(bssl::Array<bool> const&)
Line
Count
Source
204
2
auto MakeConstSpan(const C &c) -> decltype(MakeConstSpan(c.data(), c.size())) {
205
2
  return MakeConstSpan(c.data(), c.size());
206
2
}
Unexecuted instantiation: decltype (MakeConstSpan(({parm#1}.data)(), ({parm#1}.size)())) bssl::MakeConstSpan<bssl::Array<unsigned char> >(bssl::Array<unsigned char> const&)
207
208
template <typename T, size_t size>
209
0
Span<const T> MakeConstSpan(T (&array)[size]) {
210
0
  return array;
211
0
}
Unexecuted instantiation: bssl::Span<ssl_cipher_st const> bssl::MakeConstSpan<ssl_cipher_st const, 24ul>(ssl_cipher_st const (&) [24ul])
Unexecuted instantiation: bssl::Span<char const* const> bssl::MakeConstSpan<char const*, 3ul>(char const* (&) [3ul])
Unexecuted instantiation: bssl::Span<SignatureAlgorithmName const> bssl::MakeConstSpan<SignatureAlgorithmName const, 13ul>(SignatureAlgorithmName const (&) [13ul])
Unexecuted instantiation: bssl::Span<bssl::VersionInfo const> bssl::MakeConstSpan<bssl::VersionInfo const, 6ul>(bssl::VersionInfo const (&) [6ul])
Unexecuted instantiation: bssl::Span<bssl::NamedGroup const> bssl::MakeConstSpan<bssl::NamedGroup const, 6ul>(bssl::NamedGroup const (&) [6ul])
212
213
BSSL_NAMESPACE_END
214
215
}  // extern C++
216
217
#endif  // !defined(BORINGSSL_NO_CXX)
218
219
#endif  // OPENSSL_HEADER_SSL_SPAN_H