Commit 2b403ec7 by Derek Mauro Committed by Copybara-Service

Cord: Avoid leaking a node if SetExpectedChecksum() is called on an

empty cord twice in a row.

PiperOrigin-RevId: 485367641
Change-Id: I6605ff25acbcef7c40b68e15a8888076a2da63be
parent d819278a
...@@ -857,6 +857,7 @@ inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const { ...@@ -857,6 +857,7 @@ inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const {
void Cord::SetExpectedChecksum(uint32_t crc) { void Cord::SetExpectedChecksum(uint32_t crc) {
auto constexpr method = CordzUpdateTracker::kSetExpectedChecksum; auto constexpr method = CordzUpdateTracker::kSetExpectedChecksum;
if (empty()) { if (empty()) {
contents_.MaybeRemoveEmptyCrcNode();
CordRep* rep = CordRepCrc::New(nullptr, crc); CordRep* rep = CordRepCrc::New(nullptr, crc);
contents_.EmplaceTree(rep, method); contents_.EmplaceTree(rep, method);
} else if (!contents_.is_tree()) { } else if (!contents_.is_tree()) {
......
...@@ -2856,6 +2856,12 @@ TEST_P(CordTest, ExpectedChecksum) { ...@@ -2856,6 +2856,12 @@ TEST_P(CordTest, ExpectedChecksum) {
EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345); EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345);
EXPECT_EQ(c1, base_value); EXPECT_EQ(c1, base_value);
// Test that setting an expected checksum again doesn't crash or leak
// memory.
c1.SetExpectedChecksum(12345);
EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345);
EXPECT_EQ(c1, base_value);
// CRC persists through copies, assignments, and moves: // CRC persists through copies, assignments, and moves:
absl::Cord c1_copy_construct = c1; absl::Cord c1_copy_construct = c1;
EXPECT_EQ(c1_copy_construct.ExpectedChecksum().value_or(0), 12345); EXPECT_EQ(c1_copy_construct.ExpectedChecksum().value_or(0), 12345);
...@@ -2968,6 +2974,12 @@ TEST_P(CordTest, ChecksummedEmptyCord) { ...@@ -2968,6 +2974,12 @@ TEST_P(CordTest, ChecksummedEmptyCord) {
EXPECT_EQ(c1, ""); EXPECT_EQ(c1, "");
EXPECT_TRUE(c1.empty()); EXPECT_TRUE(c1.empty());
// Test that setting an expected checksum again doesn't crash or leak memory.
c1.SetExpectedChecksum(12345);
EXPECT_EQ(c1.ExpectedChecksum().value_or(0), 12345);
EXPECT_EQ(c1, "");
EXPECT_TRUE(c1.empty());
// CRC persists through copies, assignments, and moves: // CRC persists through copies, assignments, and moves:
absl::Cord c1_copy_construct = c1; absl::Cord c1_copy_construct = c1;
EXPECT_EQ(c1_copy_construct.ExpectedChecksum().value_or(0), 12345); EXPECT_EQ(c1_copy_construct.ExpectedChecksum().value_or(0), 12345);
......
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