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");  // NOLINT
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);  // NOLINT
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);  // NOLINT
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);  // NOLINT
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(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 #if !defined(_WIN32)
119   // %z* format doesn't seem to be supported by MSVS.
120   TestAgainstLibc<long>("%zd-%zd", LONG_MIN, LONG_MAX);
121   TestAgainstLibc<unsigned long>("%zu-%zu", 0, ULONG_MAX);
122   TestAgainstLibc<unsigned long>("%zx-%zx", 0, ULONG_MAX);
123 #endif
124 }
125 
126 TEST(Printf, Padding) {
127   TestAgainstLibc<int>("%3d - %3d", 1, 0);
128   TestAgainstLibc<int>("%3d - %3d", -1, 123);
129   TestAgainstLibc<int>("%3d - %3d", -1, -123);
130   TestAgainstLibc<int>("%3d - %3d", 12, 1234);
131   TestAgainstLibc<int>("%3d - %3d", -12, -1234);
132   TestAgainstLibc<int>("%03d - %03d", 1, 0);
133   TestAgainstLibc<int>("%03d - %03d", -1, 123);
134   TestAgainstLibc<int>("%03d - %03d", -1, -123);
135   TestAgainstLibc<int>("%03d - %03d", 12, 1234);
136   TestAgainstLibc<int>("%03d - %03d", -12, -1234);
137 }
138 
139 TEST(Printf, Precision) {
140   char buf[1024];
141   uptr len = internal_snprintf(buf, sizeof(buf), "%.*s", 3, "12345");
142   EXPECT_EQ(3U, len);
143   EXPECT_STREQ("123", buf);
144   len = internal_snprintf(buf, sizeof(buf), "%.*s", 6, "12345");
145   EXPECT_EQ(5U, len);
146   EXPECT_STREQ("12345", buf);
147   len = internal_snprintf(buf, sizeof(buf), "%-6s", "12345");
148   EXPECT_EQ(6U, len);
149   EXPECT_STREQ("12345 ", buf);
150   // Check that width does not overflow the smaller buffer, although
151   // 10 chars is requested, it stops at the buffer size, 8.
152   len = internal_snprintf(buf, 8, "%-10s", "12345");  // NOLINT
153   EXPECT_EQ(10U, len);  // The required size reported.
154   EXPECT_STREQ("12345  ", buf);
155 }
156 
157 }  // namespace __sanitizer
158