diff options
author | Abseil Team <absl-team@google.com> | 2023-02-15 23:21:19 (GMT) |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-02-15 23:22:10 (GMT) |
commit | f063cd25c90cbd4089a0ff96f5991df4f2721338 (patch) | |
tree | 5bad6a1e75e225fbac4d79058c13fe05ef78e151 | |
parent | 2057566e4e16c88f1fea4d6c96b2e2bfb87507a6 (diff) | |
download | googletest-f063cd25c90cbd4089a0ff96f5991df4f2721338.zip googletest-f063cd25c90cbd4089a0ff96f5991df4f2721338.tar.gz googletest-f063cd25c90cbd4089a0ff96f5991df4f2721338.tar.bz2 |
Remove strdup usage
PiperOrigin-RevId: 509947007
Change-Id: I31e1274afa889776829c877c40c9af589298dcf2
-rw-r--r-- | googletest/include/gtest/internal/gtest-port.h | 17 | ||||
-rw-r--r-- | googletest/src/gtest-death-test.cc | 94 | ||||
-rw-r--r-- | googletest/src/gtest-port.cc | 42 | ||||
-rw-r--r-- | googletest/test/gtest_unittest.cc | 16 |
4 files changed, 54 insertions, 115 deletions
diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index bedd67d..ae7fb35 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -923,7 +923,7 @@ class GTEST_API_ RE { ~RE(); // Returns the string representation of the regex. - const char* pattern() const { return pattern_; } + const char* pattern() const { return pattern_.c_str(); } // FullMatch(str, re) returns true if and only if regular expression re // matches the entire str. @@ -941,7 +941,7 @@ class GTEST_API_ RE { private: void Init(const char* regex); - const char* pattern_; + std::string pattern_; bool is_valid_; #if GTEST_USES_POSIX_RE @@ -951,7 +951,7 @@ class GTEST_API_ RE { #else // GTEST_USES_SIMPLE_RE - const char* full_pattern_; // For FullMatch(); + std::string full_pattern_; // For FullMatch(); #endif }; @@ -2032,7 +2032,6 @@ inline int DoIsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return stricmp(s1, s2); } -inline char* StrDup(const char* src) { return strdup(src); } #else // !__BORLANDC__ #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \ GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM) @@ -2043,24 +2042,14 @@ inline int DoIsATTY(int fd) { return _isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); } -inline char* StrDup(const char* src) { return _strdup(src); } #endif // __BORLANDC__ -#elif GTEST_OS_ESP8266 - -inline int DoIsATTY(int fd) { return isatty(fd); } -inline int StrCaseCmp(const char* s1, const char* s2) { - return strcasecmp(s1, s2); -} -inline char* StrDup(const char* src) { return strdup(src); } - #else inline int DoIsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); } -inline char* StrDup(const char* src) { return strdup(src); } #endif // GTEST_OS_WINDOWS diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc index b6968a9..7fcf9bf 100644 --- a/googletest/src/gtest-death-test.cc +++ b/googletest/src/gtest-death-test.cc @@ -33,7 +33,9 @@ #include "gtest/gtest-death-test.h" #include <functional> +#include <memory> #include <utility> +#include <vector> #include "gtest/internal/custom/gtest.h" #include "gtest/internal/gtest-port.h" @@ -621,6 +623,17 @@ bool DeathTestImpl::Passed(bool status_ok) { return success; } +// Note: The return value points into args, so the return value's lifetime is +// bound to that of args. +std::unique_ptr<char*[]> CreateArgvFromArgs(std::vector<std::string>& args) { + auto result = std::make_unique<char*[]>(args.size() + 1); + for (size_t i = 0; i < args.size(); ++i) { + result[i] = &args[i][0]; + } + result[args.size()] = nullptr; // extra null terminator + return result; +} + #if GTEST_OS_WINDOWS // WindowsDeathTest implements death tests on Windows. Due to the // specifics of starting new processes on Windows, death tests there are @@ -836,36 +849,6 @@ class FuchsiaDeathTest : public DeathTestImpl { zx::socket stderr_socket_; }; -// Utility class for accumulating command-line arguments. -class Arguments { - public: - Arguments() { args_.push_back(nullptr); } - - ~Arguments() { - for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); - ++i) { - free(*i); - } - } - void AddArgument(const char* argument) { - args_.insert(args_.end() - 1, posix::StrDup(argument)); - } - - template <typename Str> - void AddArguments(const ::std::vector<Str>& arguments) { - for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); - i != arguments.end(); ++i) { - args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); - } - } - char* const* Argv() { return &args_[0]; } - - int size() { return static_cast<int>(args_.size()) - 1; } - - private: - std::vector<char*> args_; -}; - // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. @@ -986,10 +969,10 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index); - Arguments args; - args.AddArguments(GetInjectableArgvs()); - args.AddArgument(filter_flag.c_str()); - args.AddArgument(internal_flag.c_str()); + + std::vector<std::string> args = GetInjectableArgvs(); + args.push_back(filter_flag); + args.push_back(internal_flag); // Build the pipe for communication with the child. zx_status_t status; @@ -1041,8 +1024,9 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { GTEST_DEATH_TEST_CHECK_(status == ZX_OK); // Spawn the child process. - status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], - args.Argv(), nullptr, 2, spawn_actions, + std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args); + status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.get(), + nullptr, 2, spawn_actions, child_process_.reset_and_get_address(), nullptr); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); @@ -1173,34 +1157,6 @@ class ExecDeathTest : public ForkingDeathTest { const int line_; }; -// Utility class for accumulating command-line arguments. -class Arguments { - public: - Arguments() { args_.push_back(nullptr); } - - ~Arguments() { - for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); - ++i) { - free(*i); - } - } - void AddArgument(const char* argument) { - args_.insert(args_.end() - 1, posix::StrDup(argument)); - } - - template <typename Str> - void AddArguments(const ::std::vector<Str>& arguments) { - for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); - i != arguments.end(); ++i) { - args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); - } - } - char* const* Argv() { return &args_[0]; } - - private: - std::vector<char*> args_; -}; - // A struct that encompasses the arguments to the child process of a // threadsafe-style death test process. struct ExecDeathTestArgs { @@ -1410,10 +1366,9 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(pipe_fd[1]); - Arguments args; - args.AddArguments(GetArgvsForDeathTestChildProcess()); - args.AddArgument(filter_flag.c_str()); - args.AddArgument(internal_flag.c_str()); + std::vector<std::string> args = GetArgvsForDeathTestChildProcess(); + args.push_back(filter_flag); + args.push_back(internal_flag); DeathTest::set_last_death_test_message(""); @@ -1422,7 +1377,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { // is necessary. FlushInfoLog(); - const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); + std::unique_ptr<char*[]> argv = CreateArgvFromArgs(args); + const pid_t child_pid = ExecDeathTestSpawnChild(argv.get(), pipe_fd[0]); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index d797fe4..105a3ec 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -668,7 +668,6 @@ RE::~RE() { regfree(&partial_regex_); regfree(&full_regex_); } - free(const_cast<char*>(pattern_)); } // 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) { // Initializes an RE from its string representation. void RE::Init(const char* regex) { - pattern_ = posix::StrDup(regex); + pattern_ = regex; // Reserves enough bytes to hold the regular expression used for a // full match. @@ -920,27 +919,26 @@ bool MatchRegexAnywhere(const char* regex, const char* str) { // Implements the RE class. -RE::~RE() { - free(const_cast<char*>(pattern_)); - free(const_cast<char*>(full_pattern_)); -} +RE::~RE() = default; // Returns true if and only if regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { - return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_.c_str(), str); } // Returns true if and only if regular expression re matches a substring of // str (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { - return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); + return re.is_valid_ && MatchRegexAnywhere(re.pattern_.c_str(), str); } // Initializes an RE from its string representation. void RE::Init(const char* regex) { - pattern_ = full_pattern_ = nullptr; + full_pattern_.clear(); + pattern_.clear(); + if (regex != nullptr) { - pattern_ = posix::StrDup(regex); + pattern_ = regex; } is_valid_ = ValidateRegex(regex); @@ -949,25 +947,19 @@ void RE::Init(const char* regex) { return; } - const size_t len = strlen(regex); // Reserves enough bytes to hold the regular expression used for a - // full match: we need space to prepend a '^', append a '$', and - // terminate the string with '\0'. - char* buffer = static_cast<char*>(malloc(len + 3)); - full_pattern_ = buffer; + // full match: we need space to prepend a '^' and append a '$'. + full_pattern_.reserve(pattern_.size() + 2); - if (*regex != '^') - *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. - - // We don't use snprintf or strncpy, as they trigger a warning when - // compiled with VC++ 8.0. - memcpy(buffer, regex, len); - buffer += len; + if (pattern_.empty() || pattern_.front() != '^') { + full_pattern_.push_back('^'); // Makes sure full_pattern_ starts with '^'. + } - if (len == 0 || regex[len - 1] != '$') - *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + full_pattern_.append(pattern_); - *buffer = '\0'; + if (pattern_.empty() || pattern_.back() != '$') { + full_pattern_.push_back('$'); // Makes sure full_pattern_ ends with '$'. + } } #endif // GTEST_USES_POSIX_RE diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index ecffa37..580ce83 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -60,6 +60,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include <cstdint> #include <map> +#include <memory> #include <ostream> #include <set> #include <string> @@ -424,10 +425,12 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test { private: void SetUp() override { - saved_tz_ = nullptr; + saved_tz_.reset(); - GTEST_DISABLE_MSC_DEPRECATED_PUSH_(/* getenv, strdup: deprecated */) - if (getenv("TZ")) saved_tz_ = strdup(getenv("TZ")); + GTEST_DISABLE_MSC_DEPRECATED_PUSH_(/* getenv: deprecated */) + if (const char* tz = getenv("TZ")) { + saved_tz_ = std::make_unique<std::string>(tz); + } GTEST_DISABLE_MSC_DEPRECATED_POP_() // Set up the time zone for FormatEpochTimeInMillisAsIso8601 to use. We @@ -437,9 +440,8 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test { } void TearDown() override { - SetTimeZone(saved_tz_); - free(const_cast<char*>(saved_tz_)); - saved_tz_ = nullptr; + SetTimeZone(saved_tz_ != nullptr ? saved_tz_->c_str() : nullptr); + saved_tz_.reset(); } static void SetTimeZone(const char* time_zone) { @@ -471,7 +473,7 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test { #endif } - const char* saved_tz_; + std::unique_ptr<std::string> saved_tz_; // Empty and null are different here }; const TimeInMillis FormatEpochTimeInMillisAsIso8601Test::kMillisPerSec; |