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 | |