Export of internal Abseil changes

--
35f516d528f4b53694ebe1f7debc023f1383cf4a by Shaindel Schwartz <shaindel@google.com>:

Internal change

PiperOrigin-RevId: 266967228

--
40a0b91769133c48e3799a99f4dd2a7ce58bac91 by Derek Mauro <dmauro@google.com>:

Prevent absl::StrCat() and absl::StrAppend() from dereferencing std::string::end()

Fixes #374

PiperOrigin-RevId: 266447391
GitOrigin-RevId: 35f516d528f4b53694ebe1f7debc023f1383cf4a
Change-Id: I82e3a1bec5fa528db90a2f67dd3bc000e8dca8ab
This commit is contained in:
Abseil Team 2019-09-03 10:53:29 -07:00 committed by Gennadiy Rozental
parent 1948f6f967
commit 9ddac555b7
2 changed files with 51 additions and 12 deletions

View file

@ -99,7 +99,7 @@ std::string StrCat(const AlphaNum& a, const AlphaNum& b) {
std::string result; std::string result;
absl::strings_internal::STLStringResizeUninitialized(&result, absl::strings_internal::STLStringResizeUninitialized(&result,
a.size() + b.size()); a.size() + b.size());
char* const begin = &*result.begin(); char* const begin = &result[0];
char* out = begin; char* out = begin;
out = Append(out, a); out = Append(out, a);
out = Append(out, b); out = Append(out, b);
@ -111,7 +111,7 @@ std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c) {
std::string result; std::string result;
strings_internal::STLStringResizeUninitialized( strings_internal::STLStringResizeUninitialized(
&result, a.size() + b.size() + c.size()); &result, a.size() + b.size() + c.size());
char* const begin = &*result.begin(); char* const begin = &result[0];
char* out = begin; char* out = begin;
out = Append(out, a); out = Append(out, a);
out = Append(out, b); out = Append(out, b);
@ -125,7 +125,7 @@ std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c,
std::string result; std::string result;
strings_internal::STLStringResizeUninitialized( strings_internal::STLStringResizeUninitialized(
&result, a.size() + b.size() + c.size() + d.size()); &result, a.size() + b.size() + c.size() + d.size());
char* const begin = &*result.begin(); char* const begin = &result[0];
char* out = begin; char* out = begin;
out = Append(out, a); out = Append(out, a);
out = Append(out, b); out = Append(out, b);
@ -144,7 +144,7 @@ std::string CatPieces(std::initializer_list<absl::string_view> pieces) {
for (const absl::string_view piece : pieces) total_size += piece.size(); for (const absl::string_view piece : pieces) total_size += piece.size();
strings_internal::STLStringResizeUninitialized(&result, total_size); strings_internal::STLStringResizeUninitialized(&result, total_size);
char* const begin = &*result.begin(); char* const begin = &result[0];
char* out = begin; char* out = begin;
for (const absl::string_view piece : pieces) { for (const absl::string_view piece : pieces) {
const size_t this_size = piece.size(); const size_t this_size = piece.size();
@ -176,7 +176,7 @@ void AppendPieces(std::string* dest,
} }
strings_internal::STLStringResizeUninitialized(dest, total_size); strings_internal::STLStringResizeUninitialized(dest, total_size);
char* const begin = &*dest->begin(); char* const begin = &(*dest)[0];
char* out = begin + old_size; char* out = begin + old_size;
for (const absl::string_view piece : pieces) { for (const absl::string_view piece : pieces) {
const size_t this_size = piece.size(); 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(); std::string::size_type old_size = dest->size();
strings_internal::STLStringResizeUninitialized( strings_internal::STLStringResizeUninitialized(
dest, old_size + a.size() + b.size()); dest, old_size + a.size() + b.size());
char* const begin = &*dest->begin(); char* const begin = &(*dest)[0];
char* out = begin + old_size; char* out = begin + old_size;
out = Append(out, a); out = Append(out, a);
out = Append(out, b); 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(); std::string::size_type old_size = dest->size();
strings_internal::STLStringResizeUninitialized( strings_internal::STLStringResizeUninitialized(
dest, old_size + a.size() + b.size() + c.size()); dest, old_size + a.size() + b.size() + c.size());
char* const begin = &*dest->begin(); char* const begin = &(*dest)[0];
char* out = begin + old_size; char* out = begin + old_size;
out = Append(out, a); out = Append(out, a);
out = Append(out, b); 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(); std::string::size_type old_size = dest->size();
strings_internal::STLStringResizeUninitialized( strings_internal::STLStringResizeUninitialized(
dest, old_size + a.size() + b.size() + c.size() + d.size()); 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; char* out = begin + old_size;
out = Append(out, a); out = Append(out, a);
out = Append(out, b); out = Append(out, b);

View file

@ -195,6 +195,21 @@ TEST(StrCat, Basics) {
EXPECT_EQ(result, "12333444455555666666777777788888888999999999"); 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(). // A minimal allocator that uses malloc().
template <typename T> template <typename T>
struct Mallocator { struct Mallocator {
@ -433,10 +448,34 @@ TEST(StrAppend, Death) {
} }
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
TEST(StrAppend, EmptyString) { TEST(StrAppend, CornerCases) {
std::string s = ""; std::string result;
absl::StrAppend(&s, s); absl::StrAppend(&result, "");
EXPECT_EQ(s, ""); 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 <typename IntType> template <typename IntType>