Prevent 32-bit size_t integer overflow in absl::Cord append and iteration PiperOrigin-RevId: 945407881 Change-Id: I7ac24c3fc113ed1d275483702f622c0f2ae11495
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc index 584a3c6..5827d89 100644 --- a/absl/strings/cord.cc +++ b/absl/strings/cord.cc
@@ -455,6 +455,9 @@ contents_.MaybeRemoveEmptyCrcNode(); if (src.empty()) return; + ABSL_RAW_CHECK(src.contents_.size() <= + std::numeric_limits<size_t>::max() - contents_.size(), + "Cord length overflow"); if (empty()) { // Since destination is empty, we can avoid allocating a node, @@ -566,6 +569,9 @@ void Cord::Prepend(const Cord& src) { contents_.MaybeRemoveEmptyCrcNode(); if (src.empty()) return; + ABSL_RAW_CHECK(src.contents_.size() <= + std::numeric_limits<size_t>::max() - contents_.size(), + "Cord length overflow"); CordRep* src_tree = src.contents_.tree(); if (src_tree != nullptr) {
diff --git a/absl/strings/cord.h b/absl/strings/cord.h index c5b2ec4..7e80259 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h
@@ -1621,11 +1621,13 @@ inline Cord::ChunkIterator::reference Cord::ChunkIterator::operator*() const { absl::base_internal::HardeningAssertGT(bytes_remaining_, size_t{0}); + ABSL_ASSERT(bytes_remaining_ >= current_chunk_.size()); return current_chunk_; } inline Cord::ChunkIterator::pointer Cord::ChunkIterator::operator->() const { absl::base_internal::HardeningAssertGT(bytes_remaining_, size_t{0}); + ABSL_ASSERT(bytes_remaining_ >= current_chunk_.size()); return ¤t_chunk_; }