1a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov//===-- sanitizer_printf_test.cc ------------------------------------------===//
2da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
3da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//                     The LLVM Compiler Infrastructure
4da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
5da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is distributed under the University of Illinois Open Source
6da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// License. See LICENSE.TXT for details.
7da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
8da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===//
9da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
10a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov// Tests for sanitizer_printf.cc
11da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
12da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===//
13a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov#include "sanitizer_common/sanitizer_common.h"
14a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h"
15da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "gtest/gtest.h"
16da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
17da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <string.h>
18da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <limits.h>
19da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
20a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonovnamespace __sanitizer {
21da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
22da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, Basic) {
23da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[1024];
24de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  uptr len = internal_snprintf(buf, sizeof(buf),
25e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov      "a%db%zdc%ue%zuf%xh%zxq%pe%sr",
26e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov      (int)-1, (long)-2, // NOLINT
27e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov      (unsigned)-4, (unsigned long)5, // NOLINT
28e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov      (unsigned)10, (unsigned long)11, // NOLINT
29da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany      (void*)0x123, "_string_");
30da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(len, strlen(buf));
3186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
3286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  std::string expectedString = "a-1b-2c4294967292e5fahbq0x";
3386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  expectedString += std::string(SANITIZER_POINTER_FORMAT_LENGTH - 3, '0');
3486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  expectedString += "123e_string_r";
3586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_STREQ(expectedString.c_str(), buf);
36da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
37da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
38da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowStr) {
39da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
40de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  uptr len = internal_snprintf(buf, 4, "%s", "abcdef");  // NOLINT
41da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(len, (uptr)6);
42a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ("abc", buf);
43da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
44da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
45da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
46da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
47da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
48da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
49da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
50da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
51da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
52da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowInt) {
53da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
54de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  internal_snprintf(buf, 4, "%d", -123456789);  // NOLINT
55a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ("-12", buf);
56da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
57da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
58da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
59da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
60da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
61da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
62da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
63da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
64da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
65da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowUint) {
66da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
6740bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  uptr val;
6840bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  if (sizeof(val) == 4) {
6940bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    val = (uptr)0x12345678;
7040bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  } else {
7140bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    val = (uptr)0x123456789ULL;
7240bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  }
7340bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  internal_snprintf(buf, 4, "a%zx", val);  // NOLINT
74a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ("a12", buf);
75da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
76da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
77da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
78da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
79da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
80da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
81da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
82da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
83da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
84da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowPtr) {
85da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
8640bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  void *p;
8740bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  if (sizeof(p) == 4) {
8840bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    p = (void*)0x1234567;
8940bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  } else {
9040bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    p = (void*)0x123456789ULL;
9140bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  }
9240bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  internal_snprintf(buf, 4, "%p", p);  // NOLINT
93a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ("0x0", buf);
94da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
95da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
96da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
97da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
98da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
99da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
100da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
101da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
102da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if defined(_WIN32)
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Oh well, MSVS headers don't define snprintf.
1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define snprintf _snprintf
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
108da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanytemplate<typename T>
109134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveevstatic void TestAgainstLibc(const char *fmt, T arg1, T arg2) {
110da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[1024];
111134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  uptr len = internal_snprintf(buf, sizeof(buf), fmt, arg1, arg2);
112da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf2[1024];
113134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  snprintf(buf2, sizeof(buf2), fmt, arg1, arg2);
114da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(len, strlen(buf));
115a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ(buf2, buf);
116da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
117da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
118da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, MinMax) {
119134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%d-%d", INT_MIN, INT_MAX);  // NOLINT
120134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<unsigned>("%u-%u", 0, UINT_MAX);  // NOLINT
121134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<unsigned>("%x-%x", 0, UINT_MAX);  // NOLINT
1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32)
1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // %z* format doesn't seem to be supported by MSVS.
1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  TestAgainstLibc<long>("%zd-%zd", LONG_MIN, LONG_MAX);  // NOLINT
1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  TestAgainstLibc<unsigned long>("%zu-%zu", 0, ULONG_MAX);  // NOLINT
126134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<unsigned long>("%zx-%zx", 0, ULONG_MAX);  // NOLINT
1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
128134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev}
129134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev
130134da448d092f82bfd5ddcdfa203c5c652c51474Sergey MatveevTEST(Printf, Padding) {
131134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", 1, 0);
132134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", -1, 123);
133134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", -1, -123);
134134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", 12, 1234);
135134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", -12, -1234);
136134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", 1, 0);
137134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", -1, 123);
138134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", -1, -123);
139134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", 12, 1234);
140134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", -12, -1234);
141da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
142da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesTEST(Printf, Precision) {
1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char buf[1024];
1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr len = internal_snprintf(buf, sizeof(buf), "%.*s", 3, "12345");
1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  EXPECT_EQ(3U, len);
1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  EXPECT_STREQ("123", buf);
1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  len = internal_snprintf(buf, sizeof(buf), "%.*s", 6, "12345");
1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  EXPECT_EQ(5U, len);
1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  EXPECT_STREQ("12345", buf);
1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
153a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov}  // namespace __sanitizer
154