Skip to content

Commit f063cd2

Browse files
Abseil Teamcopybara-github
authored andcommitted
Remove strdup usage
PiperOrigin-RevId: 509947007 Change-Id: I31e1274afa889776829c877c40c9af589298dcf2
1 parent 2057566 commit f063cd2

File tree

4 files changed

+54
-115
lines changed

4 files changed

+54
-115
lines changed

googletest/include/gtest/internal/gtest-port.h

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ class GTEST_API_ RE {
923923
~RE();
924924

925925
// Returns the string representation of the regex.
926-
const char* pattern() const { return pattern_; }
926+
const char* pattern() const { return pattern_.c_str(); }
927927

928928
// FullMatch(str, re) returns true if and only if regular expression re
929929
// matches the entire str.
@@ -941,7 +941,7 @@ class GTEST_API_ RE {
941941

942942
private:
943943
void Init(const char* regex);
944-
const char* pattern_;
944+
std::string pattern_;
945945
bool is_valid_;
946946

947947
#if GTEST_USES_POSIX_RE
@@ -951,7 +951,7 @@ class GTEST_API_ RE {
951951

952952
#else // GTEST_USES_SIMPLE_RE
953953

954-
const char* full_pattern_; // For FullMatch();
954+
std::string full_pattern_; // For FullMatch();
955955

956956
#endif
957957
};
@@ -2032,7 +2032,6 @@ inline int DoIsATTY(int fd) { return isatty(fd); }
20322032
inline int StrCaseCmp(const char* s1, const char* s2) {
20332033
return stricmp(s1, s2);
20342034
}
2035-
inline char* StrDup(const char* src) { return strdup(src); }
20362035
#else // !__BORLANDC__
20372036
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \
20382037
GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM)
@@ -2043,24 +2042,14 @@ inline int DoIsATTY(int fd) { return _isatty(fd); }
20432042
inline int StrCaseCmp(const char* s1, const char* s2) {
20442043
return _stricmp(s1, s2);
20452044
}
2046-
inline char* StrDup(const char* src) { return _strdup(src); }
20472045
#endif // __BORLANDC__
20482046

2049-
#elif GTEST_OS_ESP8266
2050-
2051-
inline int DoIsATTY(int fd) { return isatty(fd); }
2052-
inline int StrCaseCmp(const char* s1, const char* s2) {
2053-
return strcasecmp(s1, s2);
2054-
}
2055-
inline char* StrDup(const char* src) { return strdup(src); }
2056-
20572047
#else
20582048

20592049
inline int DoIsATTY(int fd) { return isatty(fd); }
20602050
inline int StrCaseCmp(const char* s1, const char* s2) {
20612051
return strcasecmp(s1, s2);
20622052
}
2063-
inline char* StrDup(const char* src) { return strdup(src); }
20642053

20652054
#endif // GTEST_OS_WINDOWS
20662055

googletest/src/gtest-death-test.cc

Lines changed: 25 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
#include "gtest/gtest-death-test.h"
3434

3535
#include <functional>
36+
#include <memory>
3637
#include <utility>
38+
#include <vector>
3739

3840
#include "gtest/internal/custom/gtest.h"
3941
#include "gtest/internal/gtest-port.h"
@@ -621,6 +623,17 @@ bool DeathTestImpl::Passed(bool status_ok) {
621623
return success;
622624
}
623625

626+
// Note: The return value points into args, so the return value's lifetime is
627+
// bound to that of args.
628+
std::unique_ptr<char*[]> CreateArgvFromArgs(std::vector<std::string>& args) {
629+
auto result = std::make_unique<char*[]>(args.size() + 1);
630+
for (size_t i = 0; i < args.size(); ++i) {
631+
result[i] = &args[i][0];
632+
}
633+
result[args.size()] = nullptr; // extra null terminator
634+
return result;
635+
}
636+
624637
#if GTEST_OS_WINDOWS
625638
// WindowsDeathTest implements death tests on Windows. Due to the
626639
// specifics of starting new processes on Windows, death tests there are
@@ -836,36 +849,6 @@ class FuchsiaDeathTest : public DeathTestImpl {
836849
zx::socket stderr_socket_;
837850
};
838851

839-
// Utility class for accumulating command-line arguments.
840-
class Arguments {
841-
public:
842-
Arguments() { args_.push_back(nullptr); }
843-
844-
~Arguments() {
845-
for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
846-
++i) {
847-
free(*i);
848-
}
849-
}
850-
void AddArgument(const char* argument) {
851-
args_.insert(args_.end() - 1, posix::StrDup(argument));
852-
}
853-
854-
template <typename Str>
855-
void AddArguments(const ::std::vector<Str>& arguments) {
856-
for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
857-
i != arguments.end(); ++i) {
858-
args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
859-
}
860-
}
861-
char* const* Argv() { return &args_[0]; }
862-
863-
int size() { return static_cast<int>(args_.size()) - 1; }
864-
865-
private:
866-
std::vector<char*> args_;
867-
};
868-
869852
// Waits for the child in a death test to exit, returning its exit
870853
// status, or 0 if no child process exists. As a side effect, sets the
871854
// outcome data member.
@@ -986,10 +969,10 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
986969
kInternalRunDeathTestFlag + "=" + file_ +
987970
"|" + StreamableToString(line_) + "|" +
988971
StreamableToString(death_test_index);
989-
Arguments args;
990-
args.AddArguments(GetInjectableArgvs());
991-
args.AddArgument(filter_flag.c_str());
992-
args.AddArgument(internal_flag.c_str());
972+
973+
std::vector<std::string> args = GetInjectableArgvs();
974+
args.push_back(filter_flag);
975+
args.push_back(internal_flag);
993976

994977
// Build the pipe for communication with the child.
995978
zx_status_t status;
@@ -1041,8 +1024,9 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
10411024
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
10421025

10431026
// Spawn the child process.
1044-
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0],
1045-
args.Argv(), nullptr, 2, spawn_actions,
1027+
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
1028+
status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.get(),
1029+
nullptr, 2, spawn_actions,
10461030
child_process_.reset_and_get_address(), nullptr);
10471031
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
10481032

@@ -1173,34 +1157,6 @@ class ExecDeathTest : public ForkingDeathTest {
11731157
const int line_;
11741158
};
11751159

1176-
// Utility class for accumulating command-line arguments.
1177-
class Arguments {
1178-
public:
1179-
Arguments() { args_.push_back(nullptr); }
1180-
1181-
~Arguments() {
1182-
for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
1183-
++i) {
1184-
free(*i);
1185-
}
1186-
}
1187-
void AddArgument(const char* argument) {
1188-
args_.insert(args_.end() - 1, posix::StrDup(argument));
1189-
}
1190-
1191-
template <typename Str>
1192-
void AddArguments(const ::std::vector<Str>& arguments) {
1193-
for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
1194-
i != arguments.end(); ++i) {
1195-
args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
1196-
}
1197-
}
1198-
char* const* Argv() { return &args_[0]; }
1199-
1200-
private:
1201-
std::vector<char*> args_;
1202-
};
1203-
12041160
// A struct that encompasses the arguments to the child process of a
12051161
// threadsafe-style death test process.
12061162
struct ExecDeathTestArgs {
@@ -1410,10 +1366,9 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
14101366
StreamableToString(line_) + "|" +
14111367
StreamableToString(death_test_index) + "|" +
14121368
StreamableToString(pipe_fd[1]);
1413-
Arguments args;
1414-
args.AddArguments(GetArgvsForDeathTestChildProcess());
1415-
args.AddArgument(filter_flag.c_str());
1416-
args.AddArgument(internal_flag.c_str());
1369+
std::vector<std::string> args = GetArgvsForDeathTestChildProcess();
1370+
args.push_back(filter_flag);
1371+
args.push_back(internal_flag);
14171372

14181373
DeathTest::set_last_death_test_message("");
14191374

@@ -1422,7 +1377,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
14221377
// is necessary.
14231378
FlushInfoLog();
14241379

1425-
const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]);
1380+
std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args);
1381+
const pid_t child_pid = ExecDeathTestSpawnChild(argv.get(), pipe_fd[0]);
14261382
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
14271383
set_child_pid(child_pid);
14281384
set_read_fd(pipe_fd[0]);

googletest/src/gtest-port.cc

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,6 @@ RE::~RE() {
668668
regfree(&partial_regex_);
669669
regfree(&full_regex_);
670670
}
671-
free(const_cast<char*>(pattern_));
672671
}
673672

674673
// Returns true if and only if regular expression re matches the entire str.
@@ -690,7 +689,7 @@ bool RE::PartialMatch(const char* str, const RE& re) {
690689

691690
// Initializes an RE from its string representation.
692691
void RE::Init(const char* regex) {
693-
pattern_ = posix::StrDup(regex);
692+
pattern_ = regex;
694693

695694
// Reserves enough bytes to hold the regular expression used for a
696695
// full match.
@@ -920,27 +919,26 @@ bool MatchRegexAnywhere(const char* regex, const char* str) {
920919

921920
// Implements the RE class.
922921

923-
RE::~RE() {
924-
free(const_cast<char*>(pattern_));
925-
free(const_cast<char*>(full_pattern_));
926-
}
922+
RE::~RE() = default;
927923

928924
// Returns true if and only if regular expression re matches the entire str.
929925
bool RE::FullMatch(const char* str, const RE& re) {
930-
return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
926+
return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_.c_str(), str);
931927
}
932928

933929
// Returns true if and only if regular expression re matches a substring of
934930
// str (including str itself).
935931
bool RE::PartialMatch(const char* str, const RE& re) {
936-
return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
932+
return re.is_valid_ && MatchRegexAnywhere(re.pattern_.c_str(), str);
937933
}
938934

939935
// Initializes an RE from its string representation.
940936
void RE::Init(const char* regex) {
941-
pattern_ = full_pattern_ = nullptr;
937+
full_pattern_.clear();
938+
pattern_.clear();
939+
942940
if (regex != nullptr) {
943-
pattern_ = posix::StrDup(regex);
941+
pattern_ = regex;
944942
}
945943

946944
is_valid_ = ValidateRegex(regex);
@@ -949,25 +947,19 @@ void RE::Init(const char* regex) {
949947
return;
950948
}
951949

952-
const size_t len = strlen(regex);
953950
// Reserves enough bytes to hold the regular expression used for a
954-
// full match: we need space to prepend a '^', append a '$', and
955-
// terminate the string with '\0'.
956-
char* buffer = static_cast<char*>(malloc(len + 3));
957-
full_pattern_ = buffer;
951+
// full match: we need space to prepend a '^' and append a '$'.
952+
full_pattern_.reserve(pattern_.size() + 2);
958953

959-
if (*regex != '^')
960-
*buffer++ = '^'; // Makes sure full_pattern_ starts with '^'.
961-
962-
// We don't use snprintf or strncpy, as they trigger a warning when
963-
// compiled with VC++ 8.0.
964-
memcpy(buffer, regex, len);
965-
buffer += len;
954+
if (pattern_.empty() || pattern_.front() != '^') {
955+
full_pattern_.push_back('^'); // Makes sure full_pattern_ starts with '^'.
956+
}
966957

967-
if (len == 0 || regex[len - 1] != '$')
968-
*buffer++ = '$'; // Makes sure full_pattern_ ends with '$'.
958+
full_pattern_.append(pattern_);
969959

970-
*buffer = '\0';
960+
if (pattern_.empty() || pattern_.back() != '$') {
961+
full_pattern_.push_back('$'); // Makes sure full_pattern_ ends with '$'.
962+
}
971963
}
972964

973965
#endif // GTEST_USES_POSIX_RE

googletest/test/gtest_unittest.cc

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
6060

6161
#include <cstdint>
6262
#include <map>
63+
#include <memory>
6364
#include <ostream>
6465
#include <set>
6566
#include <string>
@@ -424,10 +425,12 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test {
424425

425426
private:
426427
void SetUp() override {
427-
saved_tz_ = nullptr;
428+
saved_tz_.reset();
428429

429-
GTEST_DISABLE_MSC_DEPRECATED_PUSH_(/* getenv, strdup: deprecated */)
430-
if (getenv("TZ")) saved_tz_ = strdup(getenv("TZ"));
430+
GTEST_DISABLE_MSC_DEPRECATED_PUSH_(/* getenv: deprecated */)
431+
if (const char* tz = getenv("TZ")) {
432+
saved_tz_ = std::make_unique<std::string>(tz);
433+
}
431434
GTEST_DISABLE_MSC_DEPRECATED_POP_()
432435

433436
// Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We
@@ -437,9 +440,8 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test {
437440
}
438441

439442
void TearDown() override {
440-
SetTimeZone(saved_tz_);
441-
free(const_cast<char*>(saved_tz_));
442-
saved_tz_ = nullptr;
443+
SetTimeZone(saved_tz_ != nullptr ? saved_tz_->c_str() : nullptr);
444+
saved_tz_.reset();
443445
}
444446

445447
static void SetTimeZone(const char* time_zone) {
@@ -471,7 +473,7 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test {
471473
#endif
472474
}
473475

474-
const char* saved_tz_;
476+
std::unique_ptr<std::string> saved_tz_; // Empty and null are different here
475477
};
476478

477479
const TimeInMillis FormatEpochTimeInMillisAsIso8601Test::kMillisPerSec;

0 commit comments

Comments
 (0)