1//===-- strings_test.cpp ----------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "tests/scudo_unit_test.h"
10
11#include "string_utils.h"
12
13#include <limits.h>
14
15TEST(ScudoStringsTest, Constructor) {
16  scudo::ScopedString Str;
17  EXPECT_EQ(0ul, Str.length());
18  EXPECT_EQ('\0', *Str.data());
19}
20
21TEST(ScudoStringsTest, Basic) {
22  scudo::ScopedString Str;
23  Str.append("a%db%zdc%ue%zuf%xh%zxq%pe%sr", static_cast<int>(-1),
24             static_cast<scudo::uptr>(-2), static_cast<unsigned>(-4),
25             static_cast<scudo::uptr>(5), static_cast<unsigned>(10),
26             static_cast<scudo::uptr>(11), reinterpret_cast<void *>(0x123),
27             "_string_");
28  EXPECT_EQ(Str.length(), strlen(Str.data()));
29
30  std::string expectedString = "a-1b-2c4294967292e5fahbq0x";
31  expectedString += std::string(SCUDO_POINTER_FORMAT_LENGTH - 3, '0');
32  expectedString += "123e_string_r";
33  EXPECT_EQ(Str.length(), strlen(Str.data()));
34  EXPECT_STREQ(expectedString.c_str(), Str.data());
35}
36
37TEST(ScudoStringsTest, Clear) {
38  scudo::ScopedString Str;
39  Str.append("123");
40  Str.clear();
41  EXPECT_EQ(0ul, Str.length());
42  EXPECT_EQ('\0', *Str.data());
43}
44
45TEST(ScudoStringsTest, ClearLarge) {
46  constexpr char appendString[] = "123";
47  scudo::ScopedString Str;
48  Str.reserve(sizeof(appendString) * 10000);
49  for (int i = 0; i < 10000; ++i)
50    Str.append(appendString);
51  Str.clear();
52  EXPECT_EQ(0ul, Str.length());
53  EXPECT_EQ('\0', *Str.data());
54}
55
56TEST(ScudoStringsTest, Precision) {
57  scudo::ScopedString Str;
58  Str.append("%.*s", 3, "12345");
59  EXPECT_EQ(Str.length(), strlen(Str.data()));
60  EXPECT_STREQ("123", Str.data());
61  Str.clear();
62  Str.append("%.*s", 6, "12345");
63  EXPECT_EQ(Str.length(), strlen(Str.data()));
64  EXPECT_STREQ("12345", Str.data());
65  Str.clear();
66  Str.append("%-6s", "12345");
67  EXPECT_EQ(Str.length(), strlen(Str.data()));
68  EXPECT_STREQ("12345 ", Str.data());
69}
70
71static void fillString(scudo::ScopedString &Str, scudo::uptr Size) {
72  for (scudo::uptr I = 0; I < Size; I++)
73    Str.append("A");
74}
75
76TEST(ScudoStringTest, PotentialOverflows) {
77  // Use a ScopedString that spans a page, and attempt to write past the end
78  // of it with variations of append. The expectation is for nothing to crash.
79  const scudo::uptr PageSize = scudo::getPageSizeCached();
80  scudo::ScopedString Str;
81  Str.reserve(2 * PageSize);
82  Str.clear();
83  fillString(Str, 2 * PageSize);
84  Str.clear();
85  fillString(Str, PageSize - 64);
86  Str.append("%-128s", "12345");
87  Str.clear();
88  fillString(Str, PageSize - 16);
89  Str.append("%024x", 12345);
90  Str.clear();
91  fillString(Str, PageSize - 16);
92  Str.append("EEEEEEEEEEEEEEEEEEEEEEEE");
93}
94
95template <typename T>
96static void testAgainstLibc(const char *Format, T Arg1, T Arg2) {
97  scudo::ScopedString Str;
98  Str.append(Format, Arg1, Arg2);
99  char Buffer[128];
100  snprintf(Buffer, sizeof(Buffer), Format, Arg1, Arg2);
101  EXPECT_EQ(Str.length(), strlen(Str.data()));
102  EXPECT_STREQ(Buffer, Str.data());
103}
104
105TEST(ScudoStringsTest, MinMax) {
106  testAgainstLibc<int>("%d-%d", INT_MIN, INT_MAX);
107  testAgainstLibc<unsigned>("%u-%u", 0, UINT_MAX);
108  testAgainstLibc<unsigned>("%x-%x", 0, UINT_MAX);
109  testAgainstLibc<long>("%zd-%zd", LONG_MIN, LONG_MAX);
110  testAgainstLibc<unsigned long>("%zu-%zu", 0, ULONG_MAX);
111  testAgainstLibc<unsigned long>("%zx-%zx", 0, ULONG_MAX);
112}
113
114TEST(ScudoStringsTest, Padding) {
115  testAgainstLibc<int>("%3d - %3d", 1, 0);
116  testAgainstLibc<int>("%3d - %3d", -1, 123);
117  testAgainstLibc<int>("%3d - %3d", -1, -123);
118  testAgainstLibc<int>("%3d - %3d", 12, 1234);
119  testAgainstLibc<int>("%3d - %3d", -12, -1234);
120  testAgainstLibc<int>("%03d - %03d", 1, 0);
121  testAgainstLibc<int>("%03d - %03d", -1, 123);
122  testAgainstLibc<int>("%03d - %03d", -1, -123);
123  testAgainstLibc<int>("%03d - %03d", 12, 1234);
124  testAgainstLibc<int>("%03d - %03d", -12, -1234);
125}
126