#include "crypto/process_bound_string.h"
#include <algorithm>
#include <string>
#include "base/test/scoped_feature_list.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace crypto {
namespace {
MATCHER_P(ContainsSubsequence, subsequence, "contains subsequence") {
return std::search(arg.begin(), arg.end(), subsequence.begin(),
subsequence.end()) != arg.end();
}
}
template <typename T>
class ProcessBoundTest : public ::testing::Test {};
typedef ::testing::Types<std::string, std::wstring, std::u16string> TestTypes;
TYPED_TEST_SUITE(ProcessBoundTest, TestTypes);
TYPED_TEST(ProcessBoundTest, TestCases) {
const size_t test_cases[] = {0, 1, 15, 16, 17};
for (const auto test_length : test_cases) {
TypeParam test_value;
for (size_t i = 0; i < test_length; i++) {
test_value.append(
1, static_cast<typename TypeParam::value_type>('0' + (i % 10)));
}
crypto::ProcessBound<TypeParam> str(test_value);
EXPECT_EQ(test_value, str.value());
}
}
TEST(ProcessBound, Copy) {
crypto::ProcessBound<std::string> str(std::string("hello"));
auto str2 = str;
EXPECT_EQ(str2.value(), str.value());
EXPECT_EQ(str.value(), "hello");
}
TEST(ProcessBound, Move) {
crypto::ProcessBound<std::string> str(std::string("hello"));
auto str2 = std::move(str);
EXPECT_EQ(str2.value(), "hello");
}
using ProcessBoundEncryptionTest = ::testing::Test;
#if BUILDFLAG(IS_WIN)
#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \
!defined(MEMORY_SANITIZER)
TEST_F(ProcessBoundEncryptionTest, Encryption) {
[[maybe_unused]] const char* data;
{
crypto::ProcessBound<std::string> process_bound(std::string("hello"));
crypto::SecureString secure = process_bound.secure_value();
constexpr std::array<uint8_t, 5> kPlainText = {'h', 'e', 'l', 'l', 'o'};
EXPECT_THAT(process_bound.maybe_encrypted_data_,
::testing::Not(ContainsSubsequence(kPlainText)));
EXPECT_STREQ(secure.c_str(), "hello");
data = secure.data();
}
#if defined(NDEBUG)
EXPECT_EQ(data[0], '\x00');
#endif
}
#endif
#endif
}