Merge 5c2144250085d5306b7b1ccf15aa5b13d9fc4715 into cd8e73f067129f8489e35c7b51c7a68552b289d2

This commit is contained in:
Ray Winkelman 2026-10-22 09:19:07 +00:00 committed by GitHub
commit 64c90b58a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 12 deletions

View File

@ -738,6 +738,29 @@ int WindowsDeathTest::Wait() {
return status();
}
namespace {
// Keep in sync with EscapeGTestFilterLiteral in gtest.cc — death-test child
// filters must treat ':' and '-' in typed-test names as literals (#5105).
std::string EscapeDeathTestFilterLiteral(const std::string& str) {
std::string out;
out.reserve(str.size());
for (char c : str) {
if (c == '\\' || c == ':' || c == '-') {
out.push_back('\\');
}
out.push_back(c);
}
return out;
}
std::string DeathTestFilterFlag(const TestInfo* info) {
return std::string("--") + GTEST_FLAG_PREFIX_ + "filter=" +
EscapeDeathTestFilterLiteral(info->test_suite_name()) + "." +
EscapeDeathTestFilterLiteral(info->name());
}
} // namespace
// The AssumeRole process for a Windows death test. It creates a child
// process with the same executable as the current process to run the
// death test. The child process is given the --gtest_filter and
@ -775,9 +798,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
FALSE, // The initial state is non-signalled.
nullptr)); // The even is unnamed.
GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
"filter=" + info->test_suite_name() + "." +
info->name();
const std::string filter_flag = DeathTestFilterFlag(info);
const std::string internal_flag =
std::string("--") + GTEST_FLAG_PREFIX_ +
"internal_run_death_test=" + file_ + "|" + StreamableToString(line_) +
@ -969,9 +990,7 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
FlushInfoLog();
// Build the child process command line.
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
"filter=" + info->test_suite_name() + "." +
info->name();
const std::string filter_flag = DeathTestFilterFlag(info);
const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
kInternalRunDeathTestFlag + "=" + file_ +
"|" + StreamableToString(line_) + "|" +
@ -1369,9 +1388,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
// it be closed when the child process does an exec:
GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
"filter=" + info->test_suite_name() + "." +
info->name();
const std::string filter_flag = DeathTestFilterFlag(info);
const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
"internal_run_death_test=" + file_ + "|" +
StreamableToString(line_) + "|" +

View File

@ -828,7 +828,7 @@ class UnitTestFilter {
explicit UnitTestFilter(const std::string& filter) {
// By design "" filter matches "" string.
std::vector<std::string> all_patterns;
SplitString(filter, ':', &all_patterns);
SplitStringUnescaped(filter, ':', &all_patterns);
const auto exact_match_patterns_begin = std::partition(
all_patterns.begin(), all_patterns.end(), &IsGlobPattern);
@ -868,8 +868,10 @@ class PositiveAndNegativeUnitTestFilter {
explicit PositiveAndNegativeUnitTestFilter(const std::string& filter) {
std::vector<std::string> positive_and_negative_filters;
// NOTE: `SplitString` always returns a non-empty container.
SplitString(filter, '-', &positive_and_negative_filters);
// NOTE: `SplitStringUnescaped` always returns a non-empty container.
// Death-test filters escape literal '-' as "\-" so typed-test names with
// hyphens are not treated as a negative filter (#5105).
SplitStringUnescaped(filter, '-', &positive_and_negative_filters);
const auto& positive_filter = positive_and_negative_filters.front();
if (positive_and_negative_filters.size() > 1) {
@ -1335,6 +1337,28 @@ void SplitString(const ::std::string& str, char delimiter,
dest->swap(parsed);
}
// Like SplitString, but treats "\<delimiter>" as a literal delimiter character
// (backslash is consumed). Used for --gtest_filter parsing.
static void SplitStringUnescaped(const ::std::string& str, char delimiter,
::std::vector<std::string>* dest) {
dest->clear();
std::string current;
for (size_t i = 0; i < str.size(); ++i) {
if (str[i] == '\\' && i + 1 < str.size()) {
current.push_back(str[++i]);
continue;
}
if (str[i] == delimiter) {
dest->push_back(current);
current.clear();
continue;
}
current.push_back(str[i]);
}
dest->push_back(current);
}
} // namespace internal
// Constructs an empty Message.