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));
3140bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  void *ptr;
3240bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  if (sizeof(ptr) == 4) {
3340bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    EXPECT_STREQ("a-1b-2c4294967292e5fahbq"
3440bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov                 "0x00000123e_string_r", buf);
3540bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  } else {
3640bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    EXPECT_STREQ("a-1b-2c4294967292e5fahbq"
3740bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov                 "0x000000000123e_string_r", buf);
3840bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  }
39da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
40da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
41da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowStr) {
42da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
43de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  uptr len = internal_snprintf(buf, 4, "%s", "abcdef");  // NOLINT
44da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(len, (uptr)6);
45a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ("abc", buf);
46da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
47da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
48da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
49da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
50da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
51da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
52da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
53da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
54da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
55da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowInt) {
56da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
57de08c02aa3007a590bfb7d43f31d5b1a0e7d337cAlexey Samsonov  internal_snprintf(buf, 4, "%d", -123456789);  // NOLINT
58a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ("-12", buf);
59da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
60da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
61da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
62da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
63da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
64da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
65da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
66da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
67da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
68da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowUint) {
69da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
7040bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  uptr val;
7140bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  if (sizeof(val) == 4) {
7240bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    val = (uptr)0x12345678;
7340bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  } else {
7440bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    val = (uptr)0x123456789ULL;
7540bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  }
7640bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  internal_snprintf(buf, 4, "a%zx", val);  // NOLINT
77a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ("a12", buf);
78da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
79da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
80da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
81da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
82da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
83da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
84da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
85da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
86da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
87da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, OverflowPtr) {
88da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[] = "123456789";
8940bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  void *p;
9040bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  if (sizeof(p) == 4) {
9140bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    p = (void*)0x1234567;
9240bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  } else {
9340bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov    p = (void*)0x123456789ULL;
9440bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  }
9540bd009d5253b3ccfad363230c2d8ac2e139f81fAlexey Samsonov  internal_snprintf(buf, 4, "%p", p);  // NOLINT
96a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ("0x0", buf);
97da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[3], 0);
98da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[4], '5');
99da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[5], '6');
100da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[6], '7');
101da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[7], '8');
102da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[8], '9');
103da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(buf[9], 0);
104da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
105da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if defined(_WIN32)
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Oh well, MSVS headers don't define snprintf.
1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define snprintf _snprintf
1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
111da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanytemplate<typename T>
112134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveevstatic void TestAgainstLibc(const char *fmt, T arg1, T arg2) {
113da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf[1024];
114134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  uptr len = internal_snprintf(buf, sizeof(buf), fmt, arg1, arg2);
115da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char buf2[1024];
116134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  snprintf(buf2, sizeof(buf2), fmt, arg1, arg2);
117da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(len, strlen(buf));
118a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov  EXPECT_STREQ(buf2, buf);
119da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
120da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
121da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(Printf, MinMax) {
122134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%d-%d", INT_MIN, INT_MAX);  // NOLINT
123134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<unsigned>("%u-%u", 0, UINT_MAX);  // NOLINT
124134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<unsigned>("%x-%x", 0, UINT_MAX);  // NOLINT
1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32)
1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // %z* format doesn't seem to be supported by MSVS.
1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  TestAgainstLibc<long>("%zd-%zd", LONG_MIN, LONG_MAX);  // NOLINT
1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  TestAgainstLibc<unsigned long>("%zu-%zu", 0, ULONG_MAX);  // NOLINT
129134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<unsigned long>("%zx-%zx", 0, ULONG_MAX);  // NOLINT
1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
131134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev}
132134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev
133134da448d092f82bfd5ddcdfa203c5c652c51474Sergey MatveevTEST(Printf, Padding) {
134134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", 1, 0);
135134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", -1, 123);
136134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", -1, -123);
137134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", 12, 1234);
138134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%3d - %3d", -12, -1234);
139134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", 1, 0);
140134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", -1, 123);
141134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", -1, -123);
142134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", 12, 1234);
143134da448d092f82bfd5ddcdfa203c5c652c51474Sergey Matveev  TestAgainstLibc<int>("%03d - %03d", -12, -1234);
144da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
145da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesTEST(Printf, Precision) {
1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char buf[1024];
1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr len = internal_snprintf(buf, sizeof(buf), "%.*s", 3, "12345");
1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  EXPECT_EQ(3U, len);
1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  EXPECT_STREQ("123", buf);
1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  len = internal_snprintf(buf, sizeof(buf), "%.*s", 6, "12345");
1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  EXPECT_EQ(5U, len);
1532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  EXPECT_STREQ("12345", buf);
1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
156a517641e8f4365fbc5e3cddf614ebc27efd69c35Alexey Samsonov}  // namespace __sanitizer
157