Skip to content

Commit 4bd5433

Browse files
Internal change
PiperOrigin-RevId: 784645799
1 parent 8828d51 commit 4bd5433

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

src/google/protobuf/io/test_zero_copy_stream.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,14 @@ class TestZeroCopyInputStream final : public ZeroCopyInputStream {
7272
<< "The last call was not a successful Next()";
7373
ABSL_CHECK_LE(static_cast<size_t>(count), last_returned_buffer_->size())
7474
<< "count must be within bounds of last buffer";
75+
// Return the backed up buffer to the front s.t. Next() can return it.
7576
buffers_.push_front(
7677
last_returned_buffer_->substr(last_returned_buffer_->size() - count));
77-
last_returned_buffer_ = nullptr;
78+
// Note that last_returned_buffer_ is moved to last_backed_up_buffer_ to
79+
// avoid use-after-free of data that was exposed to users but not backed up.
80+
// For example, ZCIS::ReadCord() reads data, then backs up unused data
81+
// before copying the data to Cord.
82+
last_backed_up_buffer_ = std::move(last_returned_buffer_);
7883
byte_count_ -= count;
7984
}
8085

@@ -109,6 +114,10 @@ class TestZeroCopyInputStream final : public ZeroCopyInputStream {
109114
// std::optional could work here, but std::unique_ptr makes it more likely
110115
// for sanitizers to detect if the string is used after it is destroyed.
111116
std::unique_ptr<std::string> last_returned_buffer_;
117+
// It is possible that some part of the buffer needs to be valid after the
118+
// unused part is backed up. Keeping last_returned_buffer_ alive broke some
119+
// tests. Instead, we temporarily store it to last_backed_up_buffer_.
120+
std::unique_ptr<std::string> last_backed_up_buffer_;
112121
int64_t byte_count_ = 0;
113122
};
114123

0 commit comments

Comments
 (0)