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
19namespace __tsan {
20
21TEST(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
34TEST(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
48TEST(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
61TEST(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
74TEST(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
87template<typename T>
88static 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
97TEST(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