diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-01-02 21:06:40 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-01-02 21:06:40 +0100 |
commit | f4a12fc67689a830e9da1c87fd11afe5bc09deb3 (patch) | |
tree | 211ae0cd022a6c11b0026ecc7761a550c584583c /security/nss/gtests/common/util.h | |
parent | f7d30133221896638f7bf4f66c504255c4b14f48 (diff) | |
download | UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.gz UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.lz UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.tar.xz UXP-f4a12fc67689a830e9da1c87fd11afe5bc09deb3.zip |
Issue #1338 - Part 2: Update NSS to 3.48-RTM
Diffstat (limited to 'security/nss/gtests/common/util.h')
-rw-r--r-- | security/nss/gtests/common/util.h | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/security/nss/gtests/common/util.h b/security/nss/gtests/common/util.h index 7ed1fd799..9a4c8da10 100644 --- a/security/nss/gtests/common/util.h +++ b/security/nss/gtests/common/util.h @@ -8,7 +8,21 @@ #define util_h__ #include <cassert> +#include <cstdlib> +#include <iomanip> +#include <iostream> +#include <sstream> +#include <sys/stat.h> #include <vector> +#if defined(_WIN32) +#include <windows.h> +#include <codecvt> +#include <direct.h> +#else +#include <unistd.h> +#endif + +#include "nspr.h" static inline std::vector<uint8_t> hex_string_to_bytes(std::string s) { std::vector<uint8_t> bytes; @@ -18,4 +32,81 @@ static inline std::vector<uint8_t> hex_string_to_bytes(std::string s) { return bytes; } +// Given a prefix, attempts to create a unique directory that the user can do +// work in without impacting other tests. For example, if given the prefix +// "scratch", a directory like "scratch05c17b25" will be created in the current +// working directory (or the location specified by NSS_GTEST_WORKDIR, if +// defined). +// Upon destruction, the implementation will attempt to delete the directory. +// However, no attempt is made to first remove files in the directory - the +// user is responsible for this. If the directory is not empty, deleting it will +// fail. +// Statistically, it is technically possible to fail to create a unique +// directory name, but this is extremely unlikely given the expected workload of +// this implementation. +class ScopedUniqueDirectory { + public: + explicit ScopedUniqueDirectory(const std::string &prefix) { + std::string path; + const char *workingDirectory = PR_GetEnvSecure("NSS_GTEST_WORKDIR"); + if (workingDirectory) { + path.assign(workingDirectory); + } + path.append(prefix); + for (int i = 0; i < RETRY_LIMIT; i++) { + std::string pathCopy(path); + // TryMakingDirectory will modify its input. If it fails, we want to throw + // away the modified result. + if (TryMakingDirectory(pathCopy)) { + mPath.assign(pathCopy); + break; + } + } + assert(mPath.length() > 0); +#if defined(_WIN32) + // sqldb always uses UTF-8 regardless of the current system locale. + DWORD len = + MultiByteToWideChar(CP_ACP, 0, mPath.data(), mPath.size(), nullptr, 0); + std::vector<wchar_t> buf(len, L'\0'); + MultiByteToWideChar(CP_ACP, 0, mPath.data(), mPath.size(), buf.data(), + buf.size()); + std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; + mUTF8Path = converter.to_bytes(std::wstring(buf.begin(), buf.end())); +#else + mUTF8Path = mPath; +#endif + } + + // NB: the directory must be empty upon destruction + ~ScopedUniqueDirectory() { assert(rmdir(mPath.c_str()) == 0); } + + const std::string &GetPath() { return mPath; } + const std::string &GetUTF8Path() { return mUTF8Path; } + + private: + static const int RETRY_LIMIT = 5; + + static void GenerateRandomName(/*in/out*/ std::string &prefix) { + std::stringstream ss; + ss << prefix; + // RAND_MAX is at least 32767. + ss << std::setfill('0') << std::setw(4) << std::hex << rand() << rand(); + // This will overwrite the value of prefix. This is a little inefficient, + // but at least it makes the code simple. + ss >> prefix; + } + + static bool TryMakingDirectory(/*in/out*/ std::string &prefix) { + GenerateRandomName(prefix); +#if defined(_WIN32) + return _mkdir(prefix.c_str()) == 0; +#else + return mkdir(prefix.c_str(), 0777) == 0; +#endif + } + + std::string mPath; + std::string mUTF8Path; +}; + #endif // util_h__ |