| 1 | //===-- sanitizer_printf_test.cpp -----------------------------------------===// |
| 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 | // Tests for sanitizer_printf.cpp |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | #include "sanitizer_common/sanitizer_common.h" |
| 13 | #include "sanitizer_common/sanitizer_libc.h" |
| 14 | #include "gtest/gtest.h" |
| 15 | |
| 16 | #include <string.h> |
| 17 | #include <limits.h> |
| 18 | |
| 19 | namespace __sanitizer { |
| 20 | |
| 21 | TEST(Printf, Basic) { |
| 22 | char buf[1024]; |
| 23 | uptr len = internal_snprintf( |
| 24 | buf, sizeof(buf), "a%db%zdc%ue%zuf%xh%zxq%pe%sr" , (int)-1, (uptr)-2, |
| 25 | (unsigned)-4, (uptr)5, (unsigned)10, (uptr)11, (void *)0x123, "_string_" ); |
| 26 | EXPECT_EQ(len, strlen(buf)); |
| 27 | |
| 28 | std::string expectedString = "a-1b-2c4294967292e5fahbq0x" ; |
| 29 | expectedString += std::string(SANITIZER_POINTER_FORMAT_LENGTH - 3, '0'); |
| 30 | expectedString += "123e_string_r" ; |
| 31 | EXPECT_STREQ(expectedString.c_str(), buf); |
| 32 | } |
| 33 | |
| 34 | TEST(Printf, OverflowStr) { |
| 35 | char buf[] = "123456789" ; |
| 36 | uptr len = internal_snprintf(buf, 4, "%s" , "abcdef" ); |
| 37 | EXPECT_EQ(len, (uptr)6); |
| 38 | EXPECT_STREQ("abc" , buf); |
| 39 | EXPECT_EQ(buf[3], 0); |
| 40 | EXPECT_EQ(buf[4], '5'); |
| 41 | EXPECT_EQ(buf[5], '6'); |
| 42 | EXPECT_EQ(buf[6], '7'); |
| 43 | EXPECT_EQ(buf[7], '8'); |
| 44 | EXPECT_EQ(buf[8], '9'); |
| 45 | EXPECT_EQ(buf[9], 0); |
| 46 | } |
| 47 | |
| 48 | TEST(Printf, OverflowInt) { |
| 49 | char buf[] = "123456789" ; |
| 50 | internal_snprintf(buf, 4, "%d" , -123456789); |
| 51 | EXPECT_STREQ("-12" , buf); |
| 52 | EXPECT_EQ(buf[3], 0); |
| 53 | EXPECT_EQ(buf[4], '5'); |
| 54 | EXPECT_EQ(buf[5], '6'); |
| 55 | EXPECT_EQ(buf[6], '7'); |
| 56 | EXPECT_EQ(buf[7], '8'); |
| 57 | EXPECT_EQ(buf[8], '9'); |
| 58 | EXPECT_EQ(buf[9], 0); |
| 59 | } |
| 60 | |
| 61 | TEST(Printf, OverflowUint) { |
| 62 | char buf[] = "123456789" ; |
| 63 | uptr val; |
| 64 | if (sizeof(val) == 4) { |
| 65 | val = (uptr)0x12345678; |
| 66 | } else { |
| 67 | val = (uptr)0x123456789ULL; |
| 68 | } |
| 69 | internal_snprintf(buf, 4, "a%zx" , val); |
| 70 | EXPECT_STREQ("a12" , buf); |
| 71 | EXPECT_EQ(buf[3], 0); |
| 72 | EXPECT_EQ(buf[4], '5'); |
| 73 | EXPECT_EQ(buf[5], '6'); |
| 74 | EXPECT_EQ(buf[6], '7'); |
| 75 | EXPECT_EQ(buf[7], '8'); |
| 76 | EXPECT_EQ(buf[8], '9'); |
| 77 | EXPECT_EQ(buf[9], 0); |
| 78 | } |
| 79 | |
| 80 | TEST(Printf, OverflowPtr) { |
| 81 | char buf[] = "123456789" ; |
| 82 | void *p; |
| 83 | if (sizeof(p) == 4) { |
| 84 | p = (void*)0x1234567; |
| 85 | } else { |
| 86 | p = (void*)0x123456789ULL; |
| 87 | } |
| 88 | internal_snprintf(buf, 4, "%p" , p); |
| 89 | EXPECT_STREQ("0x0" , buf); |
| 90 | EXPECT_EQ(buf[3], 0); |
| 91 | EXPECT_EQ(buf[4], '5'); |
| 92 | EXPECT_EQ(buf[5], '6'); |
| 93 | EXPECT_EQ(buf[6], '7'); |
| 94 | EXPECT_EQ(buf[7], '8'); |
| 95 | EXPECT_EQ(buf[8], '9'); |
| 96 | EXPECT_EQ(buf[9], 0); |
| 97 | } |
| 98 | |
| 99 | #if defined(_WIN32) |
| 100 | // Oh well, MSVS headers don't define snprintf. |
| 101 | # define snprintf _snprintf |
| 102 | #endif |
| 103 | |
| 104 | template<typename T> |
| 105 | static void TestAgainstLibc(const char *fmt, T arg1, T arg2) { |
| 106 | char buf[1024]; |
| 107 | uptr len = internal_snprintf(buf, sizeof(buf), fmt, arg1, arg2); |
| 108 | char buf2[1024]; |
| 109 | snprintf(buf2, sizeof(buf2), fmt, arg1, arg2); |
| 110 | EXPECT_EQ(len, strlen(s: buf)); |
| 111 | EXPECT_STREQ(buf2, buf); |
| 112 | } |
| 113 | |
| 114 | TEST(Printf, MinMax) { |
| 115 | TestAgainstLibc<int>("%d-%d" , INT_MIN, INT_MAX); |
| 116 | TestAgainstLibc<unsigned>("%u-%u" , 0, UINT_MAX); |
| 117 | TestAgainstLibc<unsigned>("%x-%x" , 0, UINT_MAX); |
| 118 | TestAgainstLibc<long>("%ld-%ld" , LONG_MIN, LONG_MAX); |
| 119 | TestAgainstLibc<unsigned long>("%lu-%lu" , 0, LONG_MAX); |
| 120 | TestAgainstLibc<unsigned long>("%lx-%lx" , 0, LONG_MAX); |
| 121 | #if !defined(_WIN32) |
| 122 | // %z* format doesn't seem to be supported by MSVS. |
| 123 | TestAgainstLibc<long>("%zd-%zd" , LONG_MIN, LONG_MAX); |
| 124 | TestAgainstLibc<unsigned long>("%zu-%zu" , 0, ULONG_MAX); |
| 125 | TestAgainstLibc<unsigned long>("%zx-%zx" , 0, ULONG_MAX); |
| 126 | #endif |
| 127 | } |
| 128 | |
| 129 | TEST(Printf, Padding) { |
| 130 | TestAgainstLibc<int>("%3d - %3d" , 1, 0); |
| 131 | TestAgainstLibc<int>("%3d - %3d" , -1, 123); |
| 132 | TestAgainstLibc<int>("%3d - %3d" , -1, -123); |
| 133 | TestAgainstLibc<int>("%3d - %3d" , 12, 1234); |
| 134 | TestAgainstLibc<int>("%3d - %3d" , -12, -1234); |
| 135 | TestAgainstLibc<int>("%03d - %03d" , 1, 0); |
| 136 | TestAgainstLibc<int>("%03d - %03d" , -1, 123); |
| 137 | TestAgainstLibc<int>("%03d - %03d" , -1, -123); |
| 138 | TestAgainstLibc<int>("%03d - %03d" , 12, 1234); |
| 139 | TestAgainstLibc<int>("%03d - %03d" , -12, -1234); |
| 140 | } |
| 141 | |
| 142 | TEST(Printf, Precision) { |
| 143 | char buf[1024]; |
| 144 | uptr len = internal_snprintf(buf, sizeof(buf), "%.*s" , 3, "12345" ); |
| 145 | EXPECT_EQ(3U, len); |
| 146 | EXPECT_STREQ("123" , buf); |
| 147 | len = internal_snprintf(buf, sizeof(buf), "%.*s" , 6, "12345" ); |
| 148 | EXPECT_EQ(5U, len); |
| 149 | EXPECT_STREQ("12345" , buf); |
| 150 | len = internal_snprintf(buf, sizeof(buf), "%-6s" , "12345" ); |
| 151 | EXPECT_EQ(6U, len); |
| 152 | EXPECT_STREQ("12345 " , buf); |
| 153 | // Check that width does not overflow the smaller buffer, although |
| 154 | // 10 chars is requested, it stops at the buffer size, 8. |
| 155 | len = internal_snprintf(buf, 8, "%-10s" , "12345" ); |
| 156 | EXPECT_EQ(10U, len); // The required size reported. |
| 157 | EXPECT_STREQ("12345 " , buf); |
| 158 | } |
| 159 | |
| 160 | } // namespace __sanitizer |
| 161 | |