Skip to content

Commit df3ea78

Browse files
authored
Patch LTS with the bug fix for absl::Status::ErasePayload. (#632)
f8fe7bd53bfed601f002f521e34ab4bc083fc28b by Matthew Brown <[email protected]>: Ensure a deep copy and proper equality on absl::Status::ErasePayload PiperOrigin-RevId: 298482742
1 parent b832dce commit df3ea78

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

absl/status/status.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,15 @@ void Status::SetPayload(absl::string_view type_url, absl::Cord payload) {
147147
bool Status::ErasePayload(absl::string_view type_url) {
148148
int index = status_internal::FindPayloadIndexByUrl(GetPayloads(), type_url);
149149
if (index != -1) {
150+
PrepareToModify();
150151
GetPayloads()->erase(GetPayloads()->begin() + index);
152+
if (GetPayloads()->empty() && message().empty()) {
153+
// Special case: If this can be represented inlined, it MUST be
154+
// inlined (EqualsSlow depends on this behavior).
155+
StatusCode c = static_cast<StatusCode>(raw_code());
156+
Unref(rep_);
157+
rep_ = CodeToInlinedRep(c);
158+
}
151159
return true;
152160
}
153161

absl/status/status_test.cc

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,25 @@ TEST(Status, TestComparePayloads) {
204204
EXPECT_EQ(bad_status1, bad_status2);
205205
}
206206

207+
TEST(Status, TestComparePayloadsAfterErase) {
208+
absl::Status payload_status(absl::StatusCode::kInternal, "");
209+
payload_status.SetPayload(kUrl1, absl::Cord(kPayload1));
210+
payload_status.SetPayload(kUrl2, absl::Cord(kPayload2));
211+
212+
absl::Status empty_status(absl::StatusCode::kInternal, "");
213+
214+
// Different payloads, not equal
215+
EXPECT_NE(payload_status, empty_status);
216+
EXPECT_TRUE(payload_status.ErasePayload(kUrl1));
217+
218+
// Still Different payloads, still not equal.
219+
EXPECT_NE(payload_status, empty_status);
220+
EXPECT_TRUE(payload_status.ErasePayload(kUrl2));
221+
222+
// Both empty payloads, should be equal
223+
EXPECT_EQ(payload_status, empty_status);
224+
}
225+
207226
PayloadsVec AllVisitedPayloads(const absl::Status& s) {
208227
PayloadsVec result;
209228

@@ -261,6 +280,36 @@ TEST(Status, ToString) {
261280
HasSubstr("[bar='\\xff']")));
262281
}
263282

283+
absl::Status EraseAndReturn(const absl::Status& base) {
284+
absl::Status copy = base;
285+
EXPECT_TRUE(copy.ErasePayload(kUrl1));
286+
return copy;
287+
}
288+
289+
TEST(Status, CopyOnWriteForErasePayload) {
290+
{
291+
absl::Status base(absl::StatusCode::kInvalidArgument, "fail");
292+
base.SetPayload(kUrl1, absl::Cord(kPayload1));
293+
EXPECT_TRUE(base.GetPayload(kUrl1).has_value());
294+
absl::Status copy = EraseAndReturn(base);
295+
EXPECT_TRUE(base.GetPayload(kUrl1).has_value());
296+
EXPECT_FALSE(copy.GetPayload(kUrl1).has_value());
297+
}
298+
{
299+
absl::Status base(absl::StatusCode::kInvalidArgument, "fail");
300+
base.SetPayload(kUrl1, absl::Cord(kPayload1));
301+
absl::Status copy = base;
302+
303+
EXPECT_TRUE(base.GetPayload(kUrl1).has_value());
304+
EXPECT_TRUE(copy.GetPayload(kUrl1).has_value());
305+
306+
EXPECT_TRUE(base.ErasePayload(kUrl1));
307+
308+
EXPECT_FALSE(base.GetPayload(kUrl1).has_value());
309+
EXPECT_TRUE(copy.GetPayload(kUrl1).has_value());
310+
}
311+
}
312+
264313
TEST(Status, CopyConstructor) {
265314
{
266315
absl::Status status;
@@ -300,6 +349,14 @@ TEST(Status, CopyAssignment) {
300349
}
301350
}
302351

352+
TEST(Status, CopyAssignmentIsNotRef) {
353+
const absl::Status status_orig(absl::StatusCode::kInvalidArgument, "message");
354+
absl::Status status_copy = status_orig;
355+
EXPECT_EQ(status_orig, status_copy);
356+
status_copy.SetPayload(kUrl1, absl::Cord(kPayload1));
357+
EXPECT_NE(status_orig, status_copy);
358+
}
359+
303360
TEST(Status, MoveConstructor) {
304361
{
305362
absl::Status status;

0 commit comments

Comments
 (0)