diff options
author | Andy Getzendanner <durandal@google.com> | 2022-11-21 21:17:53 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2022-11-21 21:18:39 -0800 |
commit | 9a7e8e36300c6d89c7f9a2539f7aabf8e0031106 (patch) | |
tree | cbf03dd0ec10bc81451b996df4c9e8437d702ca1 /absl/log/internal/log_message.cc | |
parent | d081b629b7c201e701911cfb4e0c99735c21c331 (diff) | |
download | abseil-9a7e8e36300c6d89c7f9a2539f7aabf8e0031106.tar.gz abseil-9a7e8e36300c6d89c7f9a2539f7aabf8e0031106.tar.bz2 abseil-9a7e8e36300c6d89c7f9a2539f7aabf8e0031106.zip |
Zero encoded_remaining when a string field doesn't fit, so that we don't leave partial data in the buffer (all decoders should ignore it anyway) and to be sure that we don't try to put any subsequent operands in either (there shouldn't be enough space).
PiperOrigin-RevId: 490143656
Change-Id: I4d743dd9214013fbd151478ef662d50affd5ff7a
Diffstat (limited to 'absl/log/internal/log_message.cc')
-rw-r--r-- | absl/log/internal/log_message.cc | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/absl/log/internal/log_message.cc b/absl/log/internal/log_message.cc index b7313551..6b4804f1 100644 --- a/absl/log/internal/log_message.cc +++ b/absl/log/internal/log_message.cc @@ -345,11 +345,13 @@ void LogMessage::FailQuietly() { } LogMessage& LogMessage::operator<<(const std::string& v) { - return LogString(false, v); + CopyToEncodedBuffer(v, StringType::kNotLiteral); + return *this; } LogMessage& LogMessage::operator<<(absl::string_view v) { - return LogString(false, v); + CopyToEncodedBuffer(v, StringType::kNotLiteral); + return *this; } LogMessage& LogMessage::operator<<(std::ostream& (*m)(std::ostream& os)) { OstreamView view(*data_); @@ -424,27 +426,28 @@ LogMessage::OstreamView::OstreamView(LogMessageData& message_data) &encoded_remaining_copy_); string_start_ = EncodeMessageStart(ValueTag::kString, encoded_remaining_copy_.size(), - &encoded_remaining_copy_); + &encoded_remaining_copy_); setp(encoded_remaining_copy_.data(), encoded_remaining_copy_.data() + encoded_remaining_copy_.size()); data_.manipulated.rdbuf(this); } LogMessage::OstreamView::~OstreamView() { - const absl::Span<const char> contents(pbase(), - static_cast<size_t>(pptr() - pbase())); - encoded_remaining_copy_.remove_prefix(contents.size()); + data_.manipulated.rdbuf(nullptr); if (!string_start_.data()) { - // The headers didn't fit; we won't write anything to the buffer, but we - // also need to zero the size of `data_->encoded_remaining` so that no more - // data is encoded. + // The second field header didn't fit. Whether the first one did or not, we + // shouldn't commit `encoded_remaining_copy_`, and we also need to zero the + // size of `data_->encoded_remaining` so that no more data are encoded. data_.encoded_remaining.remove_suffix(data_.encoded_remaining.size()); - } else if (!contents.empty()) { - EncodeMessageLength(string_start_, &encoded_remaining_copy_); - EncodeMessageLength(message_start_, &encoded_remaining_copy_); - data_.encoded_remaining = encoded_remaining_copy_; + return; } - data_.manipulated.rdbuf(nullptr); + const absl::Span<const char> contents(pbase(), + static_cast<size_t>(pptr() - pbase())); + if (contents.empty()) return; + encoded_remaining_copy_.remove_prefix(contents.size()); + EncodeMessageLength(string_start_, &encoded_remaining_copy_); + EncodeMessageLength(message_start_, &encoded_remaining_copy_); + data_.encoded_remaining = encoded_remaining_copy_; } std::ostream& LogMessage::OstreamView::stream() { return data_.manipulated; } @@ -511,21 +514,31 @@ void LogMessage::LogBacktraceIfNeeded() { view.stream() << ") "; } -// Encodes a partial `logging.proto.Event` containing the specified string data -// into `data_->encoded_remaining`. -LogMessage& LogMessage::LogString(bool literal, absl::string_view str) { - // Don't commit the MessageStart if the String tag_type and length don't fit. +// Encodes into `data_->encoded_remaining` a partial `logging.proto.Event` +// containing the specified string data using a `Value` field appropriate to +// `str_type`. Truncates `str` if necessary, but emits nothing and marks the +// buffer full if even the field headers do not fit. +void LogMessage::CopyToEncodedBuffer(absl::string_view str, + StringType str_type) { auto encoded_remaining_copy = data_->encoded_remaining; auto start = EncodeMessageStart( EventTag::kValue, BufferSizeFor(WireType::kLengthDelimited) + str.size(), &encoded_remaining_copy); - if (EncodeStringTruncate( - literal ? ValueTag::kStringLiteral : ValueTag::kString, str, - &encoded_remaining_copy)) { + // If the `logging.proto.Event.value` field header did not fit, + // `EncodeMessageStart` will have zeroed `encoded_remaining_copy`'s size and + // `EncodeStringTruncate` will fail too. + if (EncodeStringTruncate(str_type == StringType::kLiteral + ? ValueTag::kStringLiteral + : ValueTag::kString, + str, &encoded_remaining_copy)) { + // The string may have been truncated, but the field header fit. EncodeMessageLength(start, &encoded_remaining_copy); data_->encoded_remaining = encoded_remaining_copy; + } else { + // The field header(s) did not fit; zero `encoded_remaining` so we don't + // write anything else later. + data_->encoded_remaining.remove_suffix(data_->encoded_remaining.size()); } - return *this; } LogMessageFatal::LogMessageFatal(const char* file, int line) |