From 9ddac555b7861dc178d0dbe758a1cfbed718784b Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 3 Sep 2019 10:53:29 -0700 Subject: Export of internal Abseil changes -- 35f516d528f4b53694ebe1f7debc023f1383cf4a by Shaindel Schwartz : Internal change PiperOrigin-RevId: 266967228 -- 40a0b91769133c48e3799a99f4dd2a7ce58bac91 by Derek Mauro : Prevent absl::StrCat() and absl::StrAppend() from dereferencing std::string::end() Fixes #374 PiperOrigin-RevId: 266447391 GitOrigin-RevId: 35f516d528f4b53694ebe1f7debc023f1383cf4a Change-Id: I82e3a1bec5fa528db90a2f67dd3bc000e8dca8ab --- absl/strings/str_cat.cc | 16 +++++++-------- absl/strings/str_cat_test.cc | 47 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc index ffe99db..9961944 100644 --- a/absl/strings/str_cat.cc +++ b/absl/strings/str_cat.cc @@ -99,7 +99,7 @@ std::string StrCat(const AlphaNum& a, const AlphaNum& b) { std::string result; absl::strings_internal::STLStringResizeUninitialized(&result, a.size() + b.size()); - char* const begin = &*result.begin(); + char* const begin = &result[0]; char* out = begin; out = Append(out, a); out = Append(out, b); @@ -111,7 +111,7 @@ std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c) { std::string result; strings_internal::STLStringResizeUninitialized( &result, a.size() + b.size() + c.size()); - char* const begin = &*result.begin(); + char* const begin = &result[0]; char* out = begin; out = Append(out, a); out = Append(out, b); @@ -125,7 +125,7 @@ std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, std::string result; strings_internal::STLStringResizeUninitialized( &result, a.size() + b.size() + c.size() + d.size()); - char* const begin = &*result.begin(); + char* const begin = &result[0]; char* out = begin; out = Append(out, a); out = Append(out, b); @@ -144,7 +144,7 @@ std::string CatPieces(std::initializer_list pieces) { for (const absl::string_view piece : pieces) total_size += piece.size(); strings_internal::STLStringResizeUninitialized(&result, total_size); - char* const begin = &*result.begin(); + char* const begin = &result[0]; char* out = begin; for (const absl::string_view piece : pieces) { const size_t this_size = piece.size(); @@ -176,7 +176,7 @@ void AppendPieces(std::string* dest, } strings_internal::STLStringResizeUninitialized(dest, total_size); - char* const begin = &*dest->begin(); + char* const begin = &(*dest)[0]; char* out = begin + old_size; for (const absl::string_view piece : pieces) { const size_t this_size = piece.size(); @@ -201,7 +201,7 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b) { std::string::size_type old_size = dest->size(); strings_internal::STLStringResizeUninitialized( dest, old_size + a.size() + b.size()); - char* const begin = &*dest->begin(); + char* const begin = &(*dest)[0]; char* out = begin + old_size; out = Append(out, a); out = Append(out, b); @@ -216,7 +216,7 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, std::string::size_type old_size = dest->size(); strings_internal::STLStringResizeUninitialized( dest, old_size + a.size() + b.size() + c.size()); - char* const begin = &*dest->begin(); + char* const begin = &(*dest)[0]; char* out = begin + old_size; out = Append(out, a); out = Append(out, b); @@ -233,7 +233,7 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, std::string::size_type old_size = dest->size(); strings_internal::STLStringResizeUninitialized( dest, old_size + a.size() + b.size() + c.size() + d.size()); - char* const begin = &*dest->begin(); + char* const begin = &(*dest)[0]; char* out = begin + old_size; out = Append(out, a); out = Append(out, b); diff --git a/absl/strings/str_cat_test.cc b/absl/strings/str_cat_test.cc index 29db9c0..be39880 100644 --- a/absl/strings/str_cat_test.cc +++ b/absl/strings/str_cat_test.cc @@ -195,6 +195,21 @@ TEST(StrCat, Basics) { EXPECT_EQ(result, "12333444455555666666777777788888888999999999"); } +TEST(StrCat, CornerCases) { + std::string result; + + result = absl::StrCat(""); // NOLINT + EXPECT_EQ(result, ""); + result = absl::StrCat("", ""); + EXPECT_EQ(result, ""); + result = absl::StrCat("", "", ""); + EXPECT_EQ(result, ""); + result = absl::StrCat("", "", "", ""); + EXPECT_EQ(result, ""); + result = absl::StrCat("", "", "", "", ""); + EXPECT_EQ(result, ""); +} + // A minimal allocator that uses malloc(). template struct Mallocator { @@ -433,10 +448,34 @@ TEST(StrAppend, Death) { } #endif // GTEST_HAS_DEATH_TEST -TEST(StrAppend, EmptyString) { - std::string s = ""; - absl::StrAppend(&s, s); - EXPECT_EQ(s, ""); +TEST(StrAppend, CornerCases) { + std::string result; + absl::StrAppend(&result, ""); + EXPECT_EQ(result, ""); + absl::StrAppend(&result, "", ""); + EXPECT_EQ(result, ""); + absl::StrAppend(&result, "", "", ""); + EXPECT_EQ(result, ""); + absl::StrAppend(&result, "", "", "", ""); + EXPECT_EQ(result, ""); + absl::StrAppend(&result, "", "", "", "", ""); + EXPECT_EQ(result, ""); +} + +TEST(StrAppend, CornerCasesNonEmptyAppend) { + for (std::string result : {"hello", "a std::string too long to fit in the SSO"}) { + const std::string expected = result; + absl::StrAppend(&result, ""); + EXPECT_EQ(result, expected); + absl::StrAppend(&result, "", ""); + EXPECT_EQ(result, expected); + absl::StrAppend(&result, "", "", ""); + EXPECT_EQ(result, expected); + absl::StrAppend(&result, "", "", "", ""); + EXPECT_EQ(result, expected); + absl::StrAppend(&result, "", "", "", "", ""); + EXPECT_EQ(result, expected); + } } template -- cgit v1.2.3