• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 24922258954

24 Apr 2026 12:23PM UTC coverage: 89.387% (-0.01%) from 89.401%
24922258954

push

github

web-flow
Merge pull request #5546 from randombit/jack/crldp-fixes

Fix some bugs relating to CRL distribution point handling

106817 of 119500 relevant lines covered (89.39%)

11464956.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.54
/src/lib/utils/data_src.cpp
1
/*
2
* DataSource
3
* (C) 1999-2007 Jack Lloyd
4
*     2005 Matthew Gregan
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8

9
#include <botan/data_src.h>
10

11
#include <botan/exceptn.h>
12
#include <botan/mem_ops.h>
13
#include <botan/internal/fmt.h>
14
#include <botan/internal/mem_utils.h>
15
#include <algorithm>
16
#include <istream>
17

18
#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
19
   #include <fstream>
20
#endif
21

22
namespace Botan {
23

24
/*
25
* Read a single byte from the DataSource
26
*/
27
size_t DataSource::read_byte(uint8_t& out) {
28,145,081✔
28
   return read(&out, 1);
28,145,081✔
29
}
30

31
/*
32
* Read a single byte from the DataSource
33
*/
34
std::optional<uint8_t> DataSource::read_byte() {
31,153,726✔
35
   uint8_t b = 0;
31,153,726✔
36
   if(this->read(&b, 1) == 1) {
31,153,726✔
37
      return b;
31,103,576✔
38
   } else {
39
      return {};
50,150✔
40
   }
41
}
42

43
/*
44
* Peek a single byte from the DataSource
45
*/
46
size_t DataSource::peek_byte(uint8_t& out) const {
54,457✔
47
   return peek(&out, 1, 0);
54,457✔
48
}
49

50
/*
51
* Discard the next N bytes of the data
52
*/
53
size_t DataSource::discard_next(size_t n) {
×
54
   uint8_t buf[64] = {0};
×
55
   size_t discarded = 0;
×
56

57
   while(n > 0) {
×
58
      const size_t got = this->read(buf, std::min(n, sizeof(buf)));
×
59
      discarded += got;
×
60
      n -= got;
×
61

62
      if(got == 0) {
×
63
         break;
64
      }
65
   }
66

67
   return discarded;
×
68
}
69

70
/*
71
* Read from a memory buffer
72
*/
73
size_t DataSource_Memory::read(uint8_t out[], size_t length) {
22,845,426✔
74
   const size_t got = std::min<size_t>(m_source.size() - m_offset, length);
22,845,426✔
75
   copy_mem(out, m_source.data() + m_offset, got);
22,845,426✔
76
   m_offset += got;
22,845,426✔
77
   return got;
22,845,426✔
78
}
79

80
bool DataSource_Memory::check_available(size_t n) {
5,663,070✔
81
   return (n <= (m_source.size() - m_offset));
5,663,070✔
82
}
83

84
/*
85
* Peek into a memory buffer
86
*/
87
size_t DataSource_Memory::peek(uint8_t out[], size_t length, size_t peek_offset) const {
489,847✔
88
   const size_t bytes_left = m_source.size() - m_offset;
489,847✔
89
   if(peek_offset >= bytes_left) {
489,847✔
90
      return 0;
91
   }
92

93
   const size_t got = std::min(bytes_left - peek_offset, length);
489,541✔
94
   copy_mem(out, &m_source[m_offset + peek_offset], got);
489,541✔
95
   return got;
489,541✔
96
}
97

98
/*
99
* Check if the memory buffer is empty
100
*/
101
bool DataSource_Memory::end_of_data() const {
413,024✔
102
   return (m_offset == m_source.size());
413,024✔
103
}
104

105
/*
106
* DataSource_Memory Constructor
107
*/
108
DataSource_Memory::DataSource_Memory(std::string_view in) : DataSource_Memory(as_span_of_bytes(in)) {}
2,679✔
109

110
/*
111
* Read from a stream
112
*/
113
size_t DataSource_Stream::read(uint8_t out[], size_t length) {
18,671,571✔
114
   m_source.read(cast_uint8_ptr_to_char(out), length);
18,671,571✔
115
   if(m_source.bad()) {
18,671,571✔
116
      throw Stream_IO_Error("DataSource_Stream::read: Source failure");
×
117
   }
118

119
   const size_t got = static_cast<size_t>(m_source.gcount());
18,671,571✔
120
   m_total_read += got;
18,671,571✔
121
   return got;
18,671,571✔
122
}
123

124
bool DataSource_Stream::check_available(size_t n) {
1,168✔
125
   const std::streampos orig_pos = m_source.tellg();
1,168✔
126
   m_source.seekg(0, std::ios::end);
1,168✔
127
   const size_t avail = static_cast<size_t>(m_source.tellg() - orig_pos);
1,168✔
128
   m_source.seekg(orig_pos);
1,168✔
129
   return (avail >= n);
1,168✔
130
}
131

132
/*
133
* Peek into a stream
134
*/
135
size_t DataSource_Stream::peek(uint8_t out[], size_t length, size_t offset) const {
8,555✔
136
   if(end_of_data()) {
8,555✔
137
      throw Invalid_State("DataSource_Stream: Cannot peek when out of data");
×
138
   }
139

140
   size_t got = 0;
8,555✔
141

142
   if(offset > 0) {
8,555✔
143
      m_source.seekg(offset, std::ios::cur);
×
144
      if(!m_source.good()) {
×
145
         m_source.clear();
×
146
         m_source.seekg(m_total_read, std::ios::beg);
×
147
         return 0;
×
148
      }
149
   }
150

151
   m_source.read(cast_uint8_ptr_to_char(out), length);
8,555✔
152
   if(m_source.bad()) {
8,555✔
153
      throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
×
154
   }
155
   got = static_cast<size_t>(m_source.gcount());
8,555✔
156

157
   if(m_source.eof()) {
8,555✔
158
      m_source.clear();
1,167✔
159
   }
160
   m_source.seekg(m_total_read, std::ios::beg);
8,555✔
161

162
   return got;
8,555✔
163
}
164

165
/*
166
* Check if the stream is empty or in error
167
*/
168
bool DataSource_Stream::end_of_data() const {
21,341✔
169
   /*
170
   Peek to trigger EOF indicator if positioned at the end of the stream.
171
   Without this, good() returns true even when all data has been read.
172
   */
173
   m_source.peek();
21,341✔
174
   return (!m_source.good());
21,341✔
175
}
176

177
/*
178
* Return a human-readable ID for this stream
179
*/
180
std::string DataSource_Stream::id() const {
×
181
   return m_identifier;
×
182
}
183

184
#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
185

186
/*
187
* DataSource_Stream Constructor
188
*/
189
DataSource_Stream::DataSource_Stream(std::string_view path, bool use_binary) :
6,072✔
190
      m_identifier(path),
6,072✔
191
      m_source_memory(std::make_unique<std::ifstream>(std::string(path), use_binary ? std::ios::binary : std::ios::in)),
16,115✔
192
      m_source(*m_source_memory),
6,072✔
193
      m_total_read(0) {
6,072✔
194
   if(!m_source.good()) {
6,072✔
195
      throw Stream_IO_Error(fmt("DataSource: Failure opening file '{}'", path));
2✔
196
   }
197
}
6,073✔
198

199
#endif
200

201
/*
202
* DataSource_Stream Constructor
203
*/
204
DataSource_Stream::DataSource_Stream(std::istream& in, std::string_view name) :
1✔
205
      m_identifier(name), m_source(in), m_total_read(0) {}
1✔
206

207
DataSource_Stream::~DataSource_Stream() = default;
12,143✔
208

209
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc