File: process_bound_string_unittest.cc

package info (click to toggle)
chromium 145.0.7632.159-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,976,224 kB
  • sloc: cpp: 36,198,469; ansic: 7,634,080; javascript: 3,564,060; python: 1,649,622; xml: 838,470; asm: 717,087; pascal: 185,708; sh: 88,786; perl: 88,718; objc: 79,984; sql: 59,811; cs: 42,452; fortran: 24,101; makefile: 21,144; tcl: 15,277; php: 14,022; yacc: 9,066; ruby: 7,553; awk: 3,720; lisp: 3,233; lex: 1,328; ada: 727; jsp: 228; sed: 36
file content (98 lines) | stat: -rw-r--r-- 3,136 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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();
}

}  // namespace

// Test fixture template
template <typename T>
class ProcessBoundTest : public ::testing::Test {};

// Define the types you want to test
typedef ::testing::Types<std::string, std::wstring, std::u16string> TestTypes;

// Register the test fixture for these types
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;

// Only Windows supports real encryption at the moment. On other platforms, the
// underlying decrypted buffer is returned and since it was never decrypted,
// Short String Optimization means that the custom allocator is never used for
// the test string, meaning it never gets cleared. Which is fine, since it was
// never encrypted anyway.
#if BUILDFLAG(IS_WIN)
// Reading into freed memory upsets sanitizers.
#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();
  }
// In debug builds, frees are poisoned after the SecureString allocator has
// zeroed it, so this check can only take place for release builds.
#if defined(NDEBUG)
  EXPECT_EQ(data[0], '\x00');
#endif  // defined(NDEBUG)
}
#endif  // !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) &&
        // !defined(MEMORY_SANITIZER)
#endif  // #if BUILDFLAG(IS_WIN)

}  // namespace crypto