Commit 86f30194 by Marcin Kowalczyk Committed by Copybara-Service

Fix a bug in `Cord::{Append,Prepend}(CordBuffer)`: call

`MaybeRemoveEmptyCrcNode()`. Otherwise appending a `CordBuffer` an empty Cord
with a CRC node crashes (`RemoveCrcNode()` which increases the refcount of a
nullptr child).

Cosmetics: in `Cord::InlineRep::AppendArray()`, return early for empty `src`
before removing the empty CRC node.
PiperOrigin-RevId: 619107278
Change-Id: I4f1bc6b75c662f4678c61e3ef310e8597d62e2e1
parent ad5499a2
...@@ -425,8 +425,8 @@ Cord& Cord::operator=(absl::string_view src) { ...@@ -425,8 +425,8 @@ Cord& Cord::operator=(absl::string_view src) {
// we keep it here to make diffs easier. // we keep it here to make diffs easier.
void Cord::InlineRep::AppendArray(absl::string_view src, void Cord::InlineRep::AppendArray(absl::string_view src,
MethodIdentifier method) { MethodIdentifier method) {
MaybeRemoveEmptyCrcNode();
if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined.
MaybeRemoveEmptyCrcNode();
size_t appended = 0; size_t appended = 0;
CordRep* rep = tree(); CordRep* rep = tree();
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
#include "absl/base/internal/per_thread_tls.h" #include "absl/base/internal/per_thread_tls.h"
#include "absl/base/macros.h" #include "absl/base/macros.h"
#include "absl/base/nullability.h" #include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h" #include "absl/base/port.h"
#include "absl/container/inlined_vector.h" #include "absl/container/inlined_vector.h"
#include "absl/crc/internal/crc_cord_state.h" #include "absl/crc/internal/crc_cord_state.h"
...@@ -1388,6 +1389,7 @@ inline void Cord::Prepend(absl::string_view src) { ...@@ -1388,6 +1389,7 @@ inline void Cord::Prepend(absl::string_view src) {
inline void Cord::Append(CordBuffer buffer) { inline void Cord::Append(CordBuffer buffer) {
if (ABSL_PREDICT_FALSE(buffer.length() == 0)) return; if (ABSL_PREDICT_FALSE(buffer.length() == 0)) return;
contents_.MaybeRemoveEmptyCrcNode();
absl::string_view short_value; absl::string_view short_value;
if (CordRep* rep = buffer.ConsumeValue(short_value)) { if (CordRep* rep = buffer.ConsumeValue(short_value)) {
contents_.AppendTree(rep, CordzUpdateTracker::kAppendCordBuffer); contents_.AppendTree(rep, CordzUpdateTracker::kAppendCordBuffer);
...@@ -1398,6 +1400,7 @@ inline void Cord::Append(CordBuffer buffer) { ...@@ -1398,6 +1400,7 @@ inline void Cord::Append(CordBuffer buffer) {
inline void Cord::Prepend(CordBuffer buffer) { inline void Cord::Prepend(CordBuffer buffer) {
if (ABSL_PREDICT_FALSE(buffer.length() == 0)) return; if (ABSL_PREDICT_FALSE(buffer.length() == 0)) return;
contents_.MaybeRemoveEmptyCrcNode();
absl::string_view short_value; absl::string_view short_value;
if (CordRep* rep = buffer.ConsumeValue(short_value)) { if (CordRep* rep = buffer.ConsumeValue(short_value)) {
contents_.PrependTree(rep, CordzUpdateTracker::kPrependCordBuffer); contents_.PrependTree(rep, CordzUpdateTracker::kPrependCordBuffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment