Skip to content

Commit fab02f7

Browse files
author
MarcoFalke
committed
streams: Fix read-past-the-end and integer overflows
1 parent 5e8e0b3 commit fab02f7

File tree

2 files changed

+12
-14
lines changed

2 files changed

+12
-14
lines changed

src/streams.h

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <serialize.h>
1010
#include <span.h>
1111
#include <support/allocators/zeroafterfree.h>
12+
#include <util/overflow.h>
1213

1314
#include <algorithm>
1415
#include <assert.h>
@@ -281,36 +282,32 @@ class CDataStream
281282
if (dst.size() == 0) return;
282283

283284
// Read from the beginning of the buffer
284-
unsigned int nReadPosNext = nReadPos + dst.size();
285-
if (nReadPosNext > vch.size()) {
285+
auto next_read_pos{CheckedAdd<uint32_t>(nReadPos, dst.size())};
286+
if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
286287
throw std::ios_base::failure("CDataStream::read(): end of data");
287288
}
288289
memcpy(dst.data(), &vch[nReadPos], dst.size());
289-
if (nReadPosNext == vch.size())
290-
{
290+
if (next_read_pos.value() == vch.size()) {
291291
nReadPos = 0;
292292
vch.clear();
293293
return;
294294
}
295-
nReadPos = nReadPosNext;
295+
nReadPos = next_read_pos.value();
296296
}
297297

298-
void ignore(int nSize)
298+
void ignore(size_t num_ignore)
299299
{
300300
// Ignore from the beginning of the buffer
301-
if (nSize < 0) {
302-
throw std::ios_base::failure("CDataStream::ignore(): nSize negative");
301+
auto next_read_pos{CheckedAdd<uint32_t>(nReadPos, num_ignore)};
302+
if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
303+
throw std::ios_base::failure("CDataStream::ignore(): end of data");
303304
}
304-
unsigned int nReadPosNext = nReadPos + nSize;
305-
if (nReadPosNext >= vch.size())
306-
{
307-
if (nReadPosNext > vch.size())
308-
throw std::ios_base::failure("CDataStream::ignore(): end of data");
305+
if (next_read_pos.value() == vch.size()) {
309306
nReadPos = 0;
310307
vch.clear();
311308
return;
312309
}
313-
nReadPos = nReadPosNext;
310+
nReadPos = next_read_pos.value();
314311
}
315312

316313
void write(Span<const value_type> src)

src/util/overflow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_UTIL_OVERFLOW_H
77

88
#include <limits>
9+
#include <optional>
910
#include <type_traits>
1011

1112
template <class T>

0 commit comments

Comments
 (0)