Skip to content

Commit d6c9f93

Browse files
ckennellycopybara-github
authored andcommitted
Validate absl::StringResizeAndOverwrite op has written bytes as expected.
PiperOrigin-RevId: 820383934 Change-Id: I45be1c15cd2080772cea9bfe267041be5b530832
1 parent 6725fe3 commit d6c9f93

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

absl/strings/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ cc_library(
150150
deps = [
151151
"//absl/base:config",
152152
"//absl/base:core_headers",
153+
"//absl/base:dynamic_annotations",
153154
"//absl/base:throw_delegate",
154155
],
155156
)
@@ -161,6 +162,7 @@ cc_test(
161162
linkopts = ABSL_DEFAULT_LINKOPTS,
162163
deps = [
163164
":resize_and_overwrite",
165+
"//absl/base:dynamic_annotations",
164166
"//absl/log:absl_check",
165167
"@googletest//:gtest",
166168
"@googletest//:gtest_main",

absl/strings/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ absl_cc_library(
151151
DEPS
152152
absl::config
153153
absl::core_headers
154+
absl::dynamic_annotations
154155
absl::throw_delegate
155156
)
156157

@@ -164,6 +165,7 @@ absl_cc_test(
164165
DEPS
165166
absl::strings_resize_and_overwrite
166167
absl::absl_check
168+
absl::dynamic_annotations
167169
GTest::gmock_main
168170
)
169171

absl/strings/resize_and_overwrite.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include <utility>
5353

5454
#include "absl/base/config.h"
55+
#include "absl/base/dynamic_annotations.h"
5556
#include "absl/base/internal/throw_delegate.h"
5657
#include "absl/base/macros.h"
5758
#include "absl/base/optimization.h"
@@ -125,7 +126,15 @@ void StringResizeAndOverwriteFallback(T& str, typename T::size_type n, Op op) {
125126
if (ABSL_PREDICT_FALSE(n > str.max_size())) {
126127
absl::base_internal::ThrowStdLengthError("absl::StringResizeAndOverwrite");
127128
}
129+
#ifdef ABSL_HAVE_MEMORY_SANITIZER
130+
auto old_size = str.size();
131+
#endif
128132
str.resize(n);
133+
#ifdef ABSL_HAVE_MEMORY_SANITIZER
134+
if (old_size < n) {
135+
ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(str.data() + old_size, n - old_size);
136+
}
137+
#endif
129138
auto new_size = std::move(op)(str.data(), n);
130139
ABSL_HARDENING_ASSERT(new_size >= 0 && new_size <= n);
131140
ABSL_HARDENING_ASSERT(str.data()[n] == typename T::value_type{});
@@ -167,6 +176,10 @@ void StringResizeAndOverwrite(T& str, typename T::size_type n, Op op) {
167176
strings_internal::StringResizeAndOverwriteFallback(str, n, op);
168177
}
169178
#endif
179+
#if defined(ABSL_HAVE_MEMORY_SANITIZER)
180+
auto shadow = __msan_test_shadow(str.data(), str.size());
181+
ABSL_ASSERT(shadow == -1);
182+
#endif
170183
}
171184

172185
ABSL_NAMESPACE_END

absl/strings/resize_and_overwrite_test.cc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <string>
2020

2121
#include "gtest/gtest.h"
22+
#include "absl/base/dynamic_annotations.h"
2223
#include "absl/log/absl_check.h"
2324

2425
namespace {
@@ -94,6 +95,39 @@ TEST_P(StringResizeAndOverwriteTest, StringResizeAndOverwriteFallback) {
9495
EXPECT_EQ(s.c_str()[param.final_size], '\0');
9596
}
9697

98+
#ifdef ABSL_HAVE_MEMORY_SANITIZER
99+
constexpr bool kMSan = true;
100+
#else
101+
constexpr bool kMSan = false;
102+
#endif
103+
104+
TEST_P(StringResizeAndOverwriteTest, Initialized) {
105+
if (!kMSan) {
106+
GTEST_SKIP() << "Skipping test without MSan.";
107+
}
108+
109+
const auto& param = GetParam();
110+
std::string s(param.initial_size, 'a');
111+
112+
auto op = [&]() {
113+
absl::StringResizeAndOverwrite(s, param.requested_capacity,
114+
[&](char*, size_t) {
115+
// Fail to initialize the buffer in full.
116+
return param.final_size;
117+
});
118+
};
119+
120+
if (param.initial_size < param.final_size) {
121+
#ifndef NDEBUG
122+
EXPECT_DEATH_IF_SUPPORTED(op(), "shadow == -1");
123+
#endif
124+
} else {
125+
// The string is fully initialized from the initial constructor, or we skip
126+
// the check in optimized builds.
127+
op();
128+
}
129+
}
130+
97131
// clang-format off
98132
INSTANTIATE_TEST_SUITE_P(StringResizeAndOverwriteTestSuite,
99133
StringResizeAndOverwriteTest,

0 commit comments

Comments
 (0)