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