aboutsummaryrefslogtreecommitdiff
path: root/lib/tsan/unit_tests/tsan_printf_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tsan/unit_tests/tsan_printf_test.cc')
-rw-r--r--lib/tsan/unit_tests/tsan_printf_test.cc106
1 files changed, 106 insertions, 0 deletions
diff --git a/lib/tsan/unit_tests/tsan_printf_test.cc b/lib/tsan/unit_tests/tsan_printf_test.cc
new file mode 100644
index 000000000000..0dfd1d2dfe42
--- /dev/null
+++ b/lib/tsan/unit_tests/tsan_printf_test.cc
@@ -0,0 +1,106 @@
+//===-- tsan_printf_test.cc -----------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer (TSan), a race detector.
+//
+//===----------------------------------------------------------------------===//
+#include "tsan_rtl.h"
+#include "gtest/gtest.h"
+
+#include <string.h>
+#include <limits.h>
+
+namespace __tsan {
+
+TEST(Printf, Basic) {
+ char buf[1024];
+ uptr len = internal_snprintf(buf, sizeof(buf),
+ "a%db%zdc%ue%zuf%xh%zxq%pe%sr",
+ (int)-1, (long)-2, // NOLINT
+ (unsigned)-4, (unsigned long)5, // NOLINT
+ (unsigned)10, (unsigned long)11, // NOLINT
+ (void*)0x123, "_string_");
+ EXPECT_EQ(len, strlen(buf));
+ EXPECT_EQ(0, strcmp(buf, "a-1b-2c4294967292e5fahbq"
+ "0x000000000123e_string_r"));
+}
+
+TEST(Printf, OverflowStr) {
+ char buf[] = "123456789";
+ uptr len = internal_snprintf(buf, 4, "%s", "abcdef"); // NOLINT
+ EXPECT_EQ(len, (uptr)6);
+ EXPECT_EQ(0, strcmp(buf, "abc"));
+ EXPECT_EQ(buf[3], 0);
+ EXPECT_EQ(buf[4], '5');
+ EXPECT_EQ(buf[5], '6');
+ EXPECT_EQ(buf[6], '7');
+ EXPECT_EQ(buf[7], '8');
+ EXPECT_EQ(buf[8], '9');
+ EXPECT_EQ(buf[9], 0);
+}
+
+TEST(Printf, OverflowInt) {
+ char buf[] = "123456789";
+ internal_snprintf(buf, 4, "%d", -123456789); // NOLINT
+ EXPECT_EQ(0, strcmp(buf, "-12"));
+ EXPECT_EQ(buf[3], 0);
+ EXPECT_EQ(buf[4], '5');
+ EXPECT_EQ(buf[5], '6');
+ EXPECT_EQ(buf[6], '7');
+ EXPECT_EQ(buf[7], '8');
+ EXPECT_EQ(buf[8], '9');
+ EXPECT_EQ(buf[9], 0);
+}
+
+TEST(Printf, OverflowUint) {
+ char buf[] = "123456789";
+ internal_snprintf(buf, 4, "a%zx", (unsigned long)0x123456789); // NOLINT
+ EXPECT_EQ(0, strcmp(buf, "a12"));
+ EXPECT_EQ(buf[3], 0);
+ EXPECT_EQ(buf[4], '5');
+ EXPECT_EQ(buf[5], '6');
+ EXPECT_EQ(buf[6], '7');
+ EXPECT_EQ(buf[7], '8');
+ EXPECT_EQ(buf[8], '9');
+ EXPECT_EQ(buf[9], 0);
+}
+
+TEST(Printf, OverflowPtr) {
+ char buf[] = "123456789";
+ internal_snprintf(buf, 4, "%p", (void*)0x123456789); // NOLINT
+ EXPECT_EQ(0, strcmp(buf, "0x0"));
+ EXPECT_EQ(buf[3], 0);
+ EXPECT_EQ(buf[4], '5');
+ EXPECT_EQ(buf[5], '6');
+ EXPECT_EQ(buf[6], '7');
+ EXPECT_EQ(buf[7], '8');
+ EXPECT_EQ(buf[8], '9');
+ EXPECT_EQ(buf[9], 0);
+}
+
+template<typename T>
+static void TestMinMax(const char *fmt, T min, T max) {
+ char buf[1024];
+ uptr len = internal_snprintf(buf, sizeof(buf), fmt, min, max);
+ char buf2[1024];
+ snprintf(buf2, sizeof(buf2), fmt, min, max);
+ EXPECT_EQ(len, strlen(buf));
+ EXPECT_EQ(0, strcmp(buf, buf2));
+}
+
+TEST(Printf, MinMax) {
+ TestMinMax<int>("%d-%d", INT_MIN, INT_MAX); // NOLINT
+ TestMinMax<long>("%zd-%zd", LONG_MIN, LONG_MAX); // NOLINT
+ TestMinMax<unsigned>("%u-%u", 0, UINT_MAX); // NOLINT
+ TestMinMax<unsigned long>("%zu-%zu", 0, ULONG_MAX); // NOLINT
+ TestMinMax<unsigned>("%x-%x", 0, UINT_MAX); // NOLINT
+ TestMinMax<unsigned long>("%zx-%zx", 0, ULONG_MAX); // NOLINT
+}
+
+} // namespace __tsan