diff options
author | MarcoFalke <falke.marco@gmail.com> | 2022-01-28 15:29:44 +0100 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2022-02-09 17:20:22 +0100 |
commit | fab02f799194c75af7def3a2ab45c443b75de230 (patch) | |
tree | 95fa221d48e3e8b917f14a8c09732724bb9b5941 /src/streams.h | |
parent | 5e8e0b3d7f6055e326bda61e60712b530e8920f0 (diff) |
streams: Fix read-past-the-end and integer overflows
Diffstat (limited to 'src/streams.h')
-rw-r--r-- | src/streams.h | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/src/streams.h b/src/streams.h index cf8b4eb96f..e485c09457 100644 --- a/src/streams.h +++ b/src/streams.h @@ -9,6 +9,7 @@ #include <serialize.h> #include <span.h> #include <support/allocators/zeroafterfree.h> +#include <util/overflow.h> #include <algorithm> #include <assert.h> @@ -281,36 +282,32 @@ public: if (dst.size() == 0) return; // Read from the beginning of the buffer - unsigned int nReadPosNext = nReadPos + dst.size(); - if (nReadPosNext > vch.size()) { + auto next_read_pos{CheckedAdd<uint32_t>(nReadPos, dst.size())}; + if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) { throw std::ios_base::failure("CDataStream::read(): end of data"); } memcpy(dst.data(), &vch[nReadPos], dst.size()); - if (nReadPosNext == vch.size()) - { + if (next_read_pos.value() == vch.size()) { nReadPos = 0; vch.clear(); return; } - nReadPos = nReadPosNext; + nReadPos = next_read_pos.value(); } - void ignore(int nSize) + void ignore(size_t num_ignore) { // Ignore from the beginning of the buffer - if (nSize < 0) { - throw std::ios_base::failure("CDataStream::ignore(): nSize negative"); + auto next_read_pos{CheckedAdd<uint32_t>(nReadPos, num_ignore)}; + if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) { + throw std::ios_base::failure("CDataStream::ignore(): end of data"); } - unsigned int nReadPosNext = nReadPos + nSize; - if (nReadPosNext >= vch.size()) - { - if (nReadPosNext > vch.size()) - throw std::ios_base::failure("CDataStream::ignore(): end of data"); + if (next_read_pos.value() == vch.size()) { nReadPos = 0; vch.clear(); return; } - nReadPos = nReadPosNext; + nReadPos = next_read_pos.value(); } void write(Span<const value_type> src) |