169 lines · cpp
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-exception6//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 Str.clear();70 Str.append("%-8s", "12345");71 EXPECT_EQ(Str.length(), strlen(Str.data()));72 EXPECT_STREQ("12345 ", Str.data());73}74 75static void fillString(scudo::ScopedString &Str, scudo::uptr Size) {76 for (scudo::uptr I = 0; I < Size; I++)77 Str.append("A");78}79 80TEST(ScudoStringTest, PotentialOverflows) {81 // Use a ScopedString that spans a page, and attempt to write past the end82 // of it with variations of append. The expectation is for nothing to crash.83 const scudo::uptr PageSize = scudo::getPageSizeCached();84 scudo::ScopedString Str;85 Str.reserve(2 * PageSize);86 Str.clear();87 fillString(Str, 2 * PageSize);88 Str.clear();89 fillString(Str, PageSize - 64);90 Str.append("%-128s", "12345");91 Str.clear();92 fillString(Str, PageSize - 16);93 Str.append("%024x", 12345);94 Str.clear();95 fillString(Str, PageSize - 16);96 Str.append("EEEEEEEEEEEEEEEEEEEEEEEE");97}98 99template <typename T>100static void testAgainstLibc(const char *Format, T Arg1, T Arg2) {101 scudo::ScopedString Str;102 Str.append(Format, Arg1, Arg2);103 char Buffer[128];104 snprintf(Buffer, sizeof(Buffer), Format, Arg1, Arg2);105 EXPECT_EQ(Str.length(), strlen(Str.data()));106 EXPECT_STREQ(Buffer, Str.data());107}108 109TEST(ScudoStringsTest, MinMax) {110 testAgainstLibc<int>("%d-%d", INT_MIN, INT_MAX);111 testAgainstLibc<unsigned>("%u-%u", 0, UINT_MAX);112 testAgainstLibc<unsigned>("%x-%x", 0, UINT_MAX);113 testAgainstLibc<long>("%zd-%zd", LONG_MIN, LONG_MAX);114 testAgainstLibc<unsigned long>("%zu-%zu", 0, ULONG_MAX);115 testAgainstLibc<unsigned long>("%zx-%zx", 0, ULONG_MAX);116}117 118TEST(ScudoStringsTest, Padding) {119 testAgainstLibc<int>("%3d - %3d", 1, 0);120 testAgainstLibc<int>("%3d - %3d", -1, 123);121 testAgainstLibc<int>("%3d - %3d", -1, -123);122 testAgainstLibc<int>("%3d - %3d", 12, 1234);123 testAgainstLibc<int>("%3d - %3d", -12, -1234);124 testAgainstLibc<int>("%03d - %03d", 1, 0);125 testAgainstLibc<int>("%03d - %03d", -1, 123);126 testAgainstLibc<int>("%03d - %03d", -1, -123);127 testAgainstLibc<int>("%03d - %03d", 12, 1234);128 testAgainstLibc<int>("%03d - %03d", -12, -1234);129}130 131#if defined(__linux__)132 133#include <sys/resource.h>134 135TEST(ScudoStringsTest, CapacityIncreaseFails) {136 scudo::ScopedString Str;137 138 rlimit Limit = {};139 EXPECT_EQ(0, getrlimit(RLIMIT_AS, &Limit));140 141 rlimit EmptyLimit = {.rlim_cur = 0, .rlim_max = Limit.rlim_max};142 EXPECT_EQ(0, setrlimit(RLIMIT_AS, &EmptyLimit));143 144 // qemu does not honor the setrlimit, so verify before proceeding.145 scudo::MemMapT MemMap;146 if (MemMap.map(/*Addr=*/0U, scudo::getPageSizeCached(), "scudo:test",147 MAP_ALLOWNOMEM)) {148 MemMap.unmap();149 setrlimit(RLIMIT_AS, &Limit);150 TEST_SKIP("Limiting address space does not prevent mmap.");151 }152 153 // Test requires that the default length is at least 6 characters.154 scudo::uptr MaxSize = Str.capacity();155 EXPECT_LE(6u, MaxSize);156 157 for (size_t i = 0; i < MaxSize - 5; i++) {158 Str.append("B");159 }160 161 // Attempt to append past the end of the current capacity.162 Str.append("%d", 12345678);163 EXPECT_EQ(MaxSize, Str.capacity());164 EXPECT_STREQ("B12345", &Str.data()[MaxSize - 6]);165 166 EXPECT_EQ(0, setrlimit(RLIMIT_AS, &Limit));167}168#endif169