Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/prevector.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,17 @@ class prevector {
/* FIXME: Because malloc/realloc here won't call new_handler if allocation fails, assert
success. These should instead use an allocator or new/delete so that handlers
are called as necessary, but performance would be slightly degraded by doing so. */
// Guard against sizeof(T)*new_capacity overflowing size_t (would wrap to a
// small allocation followed by an out-of-bounds write). Compared in size_t
// to match the multiplication below; only rejects sizes that can never
// represent a valid object.
if ((size_t)new_capacity > SIZE_MAX / sizeof(T)) { new_handler_terminate(); }
_union.indirect = static_cast<char*>(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity));
if (!_union.indirect) { new_handler_terminate(); }
_union.capacity = new_capacity;
} else {
// Guard against sizeof(T)*new_capacity overflowing size_t (see above).
if ((size_t)new_capacity > SIZE_MAX / sizeof(T)) { new_handler_terminate(); }
char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity));
if (!new_indirect) { new_handler_terminate(); }
T* src = direct_ptr(0);
Expand Down
9 changes: 9 additions & 0 deletions src/streams.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,15 @@ class CBaseDataStream
throw std::ios_base::failure("CBaseDataStream::read(): cannot read from null pointer");
}

// Bounds-check in full-width size_t before the (unsigned int) math below, which
// would otherwise truncate nReadPos + nSize on 64-bit and could wrap past the
// buffer. (vch.size() - nReadPos) is safe: nReadPos <= vch.size() is an invariant.
// This only rejects reads that already run past the end of data; valid reads are
// unaffected and still take the existing path below.
if (nSize > vch.size() - nReadPos) {
throw std::ios_base::failure("CBaseDataStream::read(): end of data");
}

// Read from the beginning of the buffer
unsigned int nReadPosNext = nReadPos + nSize;
if (nReadPosNext >= vch.size())
Expand Down
Loading