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
TEST(ScudoStringsTest,Basic)15 TEST(ScudoStringsTest, Basic) {
16 scudo::ScopedString Str(128);
17 Str.append("a%db%zdc%ue%zuf%xh%zxq%pe%sr", static_cast<int>(-1),
18 static_cast<scudo::uptr>(-2), static_cast<unsigned>(-4),
19 static_cast<scudo::uptr>(5), static_cast<unsigned>(10),
20 static_cast<scudo::uptr>(11), reinterpret_cast<void *>(0x123),
21 "_string_");
22 EXPECT_EQ(Str.length(), strlen(Str.data()));
23
24 std::string expectedString = "a-1b-2c4294967292e5fahbq0x";
25 expectedString += std::string(SCUDO_POINTER_FORMAT_LENGTH - 3, '0');
26 expectedString += "123e_string_r";
27 EXPECT_EQ(Str.length(), strlen(Str.data()));
28 EXPECT_STREQ(expectedString.c_str(), Str.data());
29 }
30
TEST(ScudoStringsTest,Precision)31 TEST(ScudoStringsTest, Precision) {
32 scudo::ScopedString Str(128);
33 Str.append("%.*s", 3, "12345");
34 EXPECT_EQ(Str.length(), strlen(Str.data()));
35 EXPECT_STREQ("123", Str.data());
36 Str.clear();
37 Str.append("%.*s", 6, "12345");
38 EXPECT_EQ(Str.length(), strlen(Str.data()));
39 EXPECT_STREQ("12345", Str.data());
40 Str.clear();
41 Str.append("%-6s", "12345");
42 EXPECT_EQ(Str.length(), strlen(Str.data()));
43 EXPECT_STREQ("12345 ", Str.data());
44 }
45
fillString(scudo::ScopedString & Str,scudo::uptr Size)46 static void fillString(scudo::ScopedString &Str, scudo::uptr Size) {
47 for (scudo::uptr I = 0; I < Size; I++)
48 Str.append("A");
49 }
50
TEST(ScudoStringTest,PotentialOverflows)51 TEST(ScudoStringTest, PotentialOverflows) {
52 // Use a ScopedString that spans a page, and attempt to write past the end
53 // of it with variations of append. The expectation is for nothing to crash.
54 const scudo::uptr PageSize = scudo::getPageSizeCached();
55 scudo::ScopedString Str(PageSize);
56 Str.clear();
57 fillString(Str, 2 * PageSize);
58 Str.clear();
59 fillString(Str, PageSize - 64);
60 Str.append("%-128s", "12345");
61 Str.clear();
62 fillString(Str, PageSize - 16);
63 Str.append("%024x", 12345);
64 Str.clear();
65 fillString(Str, PageSize - 16);
66 Str.append("EEEEEEEEEEEEEEEEEEEEEEEE");
67 }
68
69 template <typename T>
testAgainstLibc(const char * Format,T Arg1,T Arg2)70 static void testAgainstLibc(const char *Format, T Arg1, T Arg2) {
71 scudo::ScopedString Str(128);
72 Str.append(Format, Arg1, Arg2);
73 char Buffer[128];
74 snprintf(Buffer, sizeof(Buffer), Format, Arg1, Arg2);
75 EXPECT_EQ(Str.length(), strlen(Str.data()));
76 EXPECT_STREQ(Buffer, Str.data());
77 }
78
TEST(ScudoStringsTest,MinMax)79 TEST(ScudoStringsTest, MinMax) {
80 testAgainstLibc<int>("%d-%d", INT_MIN, INT_MAX);
81 testAgainstLibc<unsigned>("%u-%u", 0, UINT_MAX);
82 testAgainstLibc<unsigned>("%x-%x", 0, UINT_MAX);
83 testAgainstLibc<long>("%zd-%zd", LONG_MIN, LONG_MAX);
84 testAgainstLibc<unsigned long>("%zu-%zu", 0, ULONG_MAX);
85 testAgainstLibc<unsigned long>("%zx-%zx", 0, ULONG_MAX);
86 }
87
TEST(ScudoStringsTest,Padding)88 TEST(ScudoStringsTest, Padding) {
89 testAgainstLibc<int>("%3d - %3d", 1, 0);
90 testAgainstLibc<int>("%3d - %3d", -1, 123);
91 testAgainstLibc<int>("%3d - %3d", -1, -123);
92 testAgainstLibc<int>("%3d - %3d", 12, 1234);
93 testAgainstLibc<int>("%3d - %3d", -12, -1234);
94 testAgainstLibc<int>("%03d - %03d", 1, 0);
95 testAgainstLibc<int>("%03d - %03d", -1, 123);
96 testAgainstLibc<int>("%03d - %03d", -1, -123);
97 testAgainstLibc<int>("%03d - %03d", 12, 1234);
98 testAgainstLibc<int>("%03d - %03d", -12, -1234);
99 }
100