1 //===-- tsan_printf_test.cc -----------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "tsan_rtl.h"
14 #include "gtest/gtest.h"
15
16 #include <string.h>
17 #include <limits.h>
18
19 namespace __tsan {
20
TEST(Printf,Basic)21 TEST(Printf, Basic) {
22 char buf[1024];
23 uptr len = internal_snprintf(buf, sizeof(buf),
24 "a%db%zdc%ue%zuf%xh%zxq%pe%sr",
25 (int)-1, (long)-2, // NOLINT
26 (unsigned)-4, (unsigned long)5, // NOLINT
27 (unsigned)10, (unsigned long)11, // NOLINT
28 (void*)0x123, "_string_");
29 EXPECT_EQ(len, strlen(buf));
30 EXPECT_EQ(0, strcmp(buf, "a-1b-2c4294967292e5fahbq"
31 "0x000000000123e_string_r"));
32 }
33
TEST(Printf,OverflowStr)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_EQ(0, strcmp(buf, "abc"));
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
TEST(Printf,OverflowInt)48 TEST(Printf, OverflowInt) {
49 char buf[] = "123456789";
50 internal_snprintf(buf, 4, "%d", -123456789); // NOLINT
51 EXPECT_EQ(0, strcmp(buf, "-12"));
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
TEST(Printf,OverflowUint)61 TEST(Printf, OverflowUint) {
62 char buf[] = "123456789";
63 internal_snprintf(buf, 4, "a%zx", (unsigned long)0x123456789); // NOLINT
64 EXPECT_EQ(0, strcmp(buf, "a12"));
65 EXPECT_EQ(buf[3], 0);
66 EXPECT_EQ(buf[4], '5');
67 EXPECT_EQ(buf[5], '6');
68 EXPECT_EQ(buf[6], '7');
69 EXPECT_EQ(buf[7], '8');
70 EXPECT_EQ(buf[8], '9');
71 EXPECT_EQ(buf[9], 0);
72 }
73
TEST(Printf,OverflowPtr)74 TEST(Printf, OverflowPtr) {
75 char buf[] = "123456789";
76 internal_snprintf(buf, 4, "%p", (void*)0x123456789); // NOLINT
77 EXPECT_EQ(0, strcmp(buf, "0x0"));
78 EXPECT_EQ(buf[3], 0);
79 EXPECT_EQ(buf[4], '5');
80 EXPECT_EQ(buf[5], '6');
81 EXPECT_EQ(buf[6], '7');
82 EXPECT_EQ(buf[7], '8');
83 EXPECT_EQ(buf[8], '9');
84 EXPECT_EQ(buf[9], 0);
85 }
86
87 template<typename T>
TestMinMax(const char * fmt,T min,T max)88 static void TestMinMax(const char *fmt, T min, T max) {
89 char buf[1024];
90 uptr len = internal_snprintf(buf, sizeof(buf), fmt, min, max);
91 char buf2[1024];
92 snprintf(buf2, sizeof(buf2), fmt, min, max);
93 EXPECT_EQ(len, strlen(buf));
94 EXPECT_EQ(0, strcmp(buf, buf2));
95 }
96
TEST(Printf,MinMax)97 TEST(Printf, MinMax) {
98 TestMinMax<int>("%d-%d", INT_MIN, INT_MAX); // NOLINT
99 TestMinMax<long>("%zd-%zd", LONG_MIN, LONG_MAX); // NOLINT
100 TestMinMax<unsigned>("%u-%u", 0, UINT_MAX); // NOLINT
101 TestMinMax<unsigned long>("%zu-%zu", 0, ULONG_MAX); // NOLINT
102 TestMinMax<unsigned>("%x-%x", 0, UINT_MAX); // NOLINT
103 TestMinMax<unsigned long>("%zx-%zx", 0, ULONG_MAX); // NOLINT
104 }
105
106 } // namespace __tsan
107