12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===-- sanitizer_format_interceptor_test.cc ------------------------------===//
24f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//
34f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//                     The LLVM Compiler Infrastructure
44f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//
54f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// This file is distributed under the University of Illinois Open Source
64f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// License. See LICENSE.TXT for details.
74f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//
84f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//===----------------------------------------------------------------------===//
94f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//
104f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// Tests for *scanf interceptors implementation in sanitizer_common.
114f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//
124f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//===----------------------------------------------------------------------===//
132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <algorithm>
14996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include <vector>
15996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
16996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "interception/interception.h"
17996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "sanitizer_test_utils.h"
18996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "sanitizer_common/sanitizer_libc.h"
192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_common.h"
20996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include "gtest/gtest.h"
21996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
22996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanovusing namespace __sanitizer;
23996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)                    \
252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  do {                                                                         \
262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ((std::vector<unsigned> *)ctx)->push_back(size);                           \
272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    ptr = ptr;                                                                 \
282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  } while (0)
292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size)                          \
312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)
322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
3344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)                         \
342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)
352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define SANITIZER_INTERCEPT_PRINTF 1
372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_common_interceptors_format.inc"
382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned I = sizeof(int);
402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned L = sizeof(long);
412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned LL = sizeof(long long);
422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned S = sizeof(short);
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned C = sizeof(char);
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned LC = sizeof(wchar_t);
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned D = sizeof(double);
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned LD = sizeof(long double);
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned F = sizeof(float);
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const unsigned P = sizeof(char *);
492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void verifyFormatResults(const char *format, unsigned n,
512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                const std::vector<unsigned> &computed_sizes,
522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                va_list expected_sizes) {
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // "+ 1" because of format string
542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ASSERT_EQ(n + 1,
552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            computed_sizes.size()) << "Unexpected number of format arguments: '"
562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                   << format << "'";
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  for (unsigned i = 0; i < n; ++i)
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    EXPECT_EQ(va_arg(expected_sizes, unsigned), computed_sizes[i + 1])
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        << "Unexpect write size for argument " << i << ", format string '"
602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        << format << "'";
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
62996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const char test_buf[] = "Test string.";
642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const size_t test_buf_size = sizeof(test_buf);
65996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
660527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanovstatic const unsigned SCANF_ARGS_MAX = 16;
670527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov
68f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanovstatic void testScanf3(void *ctx, int result, bool allowGnuMalloc,
69f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov                       const char *format, ...) {
70996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  va_list ap;
71996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  va_start(ap, format);
72f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  scanf_common(ctx, result, allowGnuMalloc, format, ap);
73996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  va_end(ap);
74996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov}
75996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
76f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanovstatic void testScanf2(const char *format, int scanf_result,
77f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov                       bool allowGnuMalloc, unsigned n,
7844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov                       va_list expected_sizes) {
79996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  std::vector<unsigned> scanf_sizes;
80996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  // 16 args should be enough.
81f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanf3((void *)&scanf_sizes, scanf_result, allowGnuMalloc, format,
822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines             test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines             test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines             test_buf, test_buf, test_buf, test_buf);
852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  verifyFormatResults(format, n, scanf_sizes, expected_sizes);
860527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov}
870527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov
880527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanovstatic void testScanf(const char *format, unsigned n, ...) {
890527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  va_list ap;
900527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  va_start(ap, n);
91f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ true, n, ap);
920527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  va_end(ap);
930527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov}
940527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov
9544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanovstatic void testScanfPartial(const char *format, int scanf_result, unsigned n,
9644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov                             ...) {
970527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  va_list ap;
980527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  va_start(ap, n);
99f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanf2(format, scanf_result, /* allowGnuMalloc */ true,  n, ap);
100f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  va_end(ap);
101f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov}
102f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov
103f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanovstatic void testScanfNoGnuMalloc(const char *format, unsigned n, ...) {
104f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  va_list ap;
105f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  va_start(ap, n);
106f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ false, n, ap);
107996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  va_end(ap);
108996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov}
109996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
110996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy StepanovTEST(SanitizerCommonInterceptors, Scanf) {
111996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%d", 1, I);
112996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%d%d%d", 3, I, I, I);
113996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("ab%u%dc", 2, I, I);
114996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%ld", 1, L);
115996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%llu", 1, LL);
1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testScanf("%qd", 1, LL);
117996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a %hd%hhx", 2, S, C);
1186503100c43c8951f436698b47362cdc8c2ec0a69Alexey Samsonov  testScanf("%c", 1, C);
1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testScanf("%lc", 1, LC);
120996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
121996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%%", 0);
122996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a%%", 0);
123996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a%%b", 0);
124996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a%%%%b", 0);
125996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a%%b%%", 0);
126996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a%%%%%%b", 0);
127996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a%%%%%b", 0);
128996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a%%%%%f", 1, F);
129996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a%%%lxb", 1, L);
130996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("a%lf%%%lxb", 2, D, L);
131996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%nf", 1, I);
132996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
133996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%10s", 1, 11);
1346503100c43c8951f436698b47362cdc8c2ec0a69Alexey Samsonov  testScanf("%10c", 1, 10);
1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testScanf("%10ls", 1, 11 * LC);
1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testScanf("%10lc", 1, 10 * LC);
137996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%%10s", 0);
138996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%*10s", 0);
139996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  testScanf("%*d", 0);
1406503100c43c8951f436698b47362cdc8c2ec0a69Alexey Samsonov
1416503100c43c8951f436698b47362cdc8c2ec0a69Alexey Samsonov  testScanf("%4d%8f%c", 3, I, F, C);
1422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testScanf("%s%d", 2, test_buf_size, I);
1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testScanf("%[abc]", 1, test_buf_size);
1443c2999e340a57a663f1b507006becfc49b368473Alexey Samsonov  testScanf("%4[bcdef]", 1, 5);
1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testScanf("%[]]", 1, test_buf_size);
1463c2999e340a57a663f1b507006becfc49b368473Alexey Samsonov  testScanf("%8[^]%d0-9-]%c", 2, 9, C);
1473c2999e340a57a663f1b507006becfc49b368473Alexey Samsonov
1483c2999e340a57a663f1b507006becfc49b368473Alexey Samsonov  testScanf("%*[^:]%n:%d:%1[ ]%n", 4, I, I, 2, I);
149c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov
150c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov  testScanf("%*d%u", 1, I);
151c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov
1524f06d0ba90aae87a21f3a7d75db985a01b8fb6d2Evgeniy Stepanov  testScanf("%c%d", 2, C, I);
1534f06d0ba90aae87a21f3a7d75db985a01b8fb6d2Evgeniy Stepanov  testScanf("%A%lf", 2, F, D);
1544f06d0ba90aae87a21f3a7d75db985a01b8fb6d2Evgeniy Stepanov
1550e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%ms %Lf", 2, P, LD);
1560e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("s%Las", 1, LD);
1570e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%ar", 1, F);
1580e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov
1590e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  // In the cases with std::min below the format spec can be interpreted as
1600e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  // either floating-something, or (GNU extension) callee-allocated string.
1610e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  // Our conservative implementation reports one of the two possibilities with
1620e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  // the least store range.
163c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov  testScanf("%a[", 0);
1640e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%a[]", 0);
1650e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%a[]]", 1, std::min(F, P));
1660e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%a[abc]", 1, std::min(F, P));
1670e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%a[^abc]", 1, std::min(F, P));
1680e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%a[ab%c] %d", 0);
1690e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%a[^ab%c] %d", 0);
1700e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%as", 1, std::min(F, P));
1710e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%aS", 1, std::min(F, P));
1720e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%a13S", 1, std::min(F, P));
1730e43e9ea9a1d5453fe1c25a6ec3927b417a8f5b1Evgeniy Stepanov  testScanf("%alS", 1, std::min(F, P));
174c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov
175f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("s%Las", 1, LD);
176f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%ar", 1, F);
177f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%a[", 1, F);
178f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%a[]", 1, F);
179f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%a[]]", 1, F);
180f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%a[abc]", 1, F);
181f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%a[^abc]", 1, F);
182f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%a[ab%c] %d", 3, F, C, I);
183f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%a[^ab%c] %d", 3, F, C, I);
184f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%as", 1, F);
185f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%aS", 1, F);
186f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%a13S", 1, F);
187f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov  testScanfNoGnuMalloc("%alS", 1, F);
188f4a1ea7e0130273039f6c76d97e852f28e572d7aEvgeniy Stepanov
189c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov  testScanf("%5$d", 0);
190c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov  testScanf("%md", 0);
191c36c168f8f482f35f200fea57dd88a888bf062fbEvgeniy Stepanov  testScanf("%m10s", 0);
1920527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov
1930527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  testScanfPartial("%d%d%d%d //1\n", 1, 1, I);
1940527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  testScanfPartial("%d%d%d%d //2\n", 2, 2, I, I);
1950527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  testScanfPartial("%d%d%d%d //3\n", 3, 3, I, I, I);
1960527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  testScanfPartial("%d%d%d%d //4\n", 4, 4, I, I, I, I);
1970527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov
19831f1941f7e2ee9548a77fb19186960b9b8a0632aEvgeniy Stepanov  testScanfPartial("%d%n%n%d //1\n", 1, 3, I, I, I);
1990527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov  testScanfPartial("%d%n%n%d //2\n", 2, 4, I, I, I, I);
2000527bf2e6aa5b35da8aa57e866287ab66af67c15Evgeniy Stepanov
2012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testScanfPartial("%d%n%n%d %s %s", 3, 5, I, I, I, I, test_buf_size);
2022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testScanfPartial("%d%n%n%d %s %s", 4, 6, I, I, I, I, test_buf_size,
2032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                   test_buf_size);
2042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void testPrintf3(void *ctx, const char *format, ...) {
2072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_list ap;
2082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_start(ap, format);
2092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  printf_common(ctx, format, ap);
2102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_end(ap);
2112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void testPrintf2(const char *format, unsigned n,
2142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                       va_list expected_sizes) {
2152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  std::vector<unsigned> printf_sizes;
2162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // 16 args should be enough.
2172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf3((void *)&printf_sizes, format,
2182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines             test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
2192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines             test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
2202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines             test_buf, test_buf, test_buf, test_buf);
2212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  verifyFormatResults(format, n, printf_sizes, expected_sizes);
2222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void testPrintf(const char *format, unsigned n, ...) {
2252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_list ap;
2262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_start(ap, n);
2272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf2(format, n, ap);
2282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  va_end(ap);
2292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesTEST(SanitizerCommonInterceptors, Printf) {
2322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Only test functionality which differs from scanf
2332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Indexed arguments
2352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%5$d", 0);
2362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%.*5$d", 0);
2372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // errno
2392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%0-m", 0);
2402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Dynamic width
2422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%*n", 1, I);
2432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%*.10n", 1, I);
2442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Precision
2462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%10.10n", 1, I);
2472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%.3s", 1, 3);
2482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%.20s", 1, test_buf_size);
2492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Dynamic precision
2512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%.*n", 1, I);
2522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%10.*n", 1, I);
2532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Dynamic precision for strings is not implemented yet.
2552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%.*s", 1, 0);
2562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Checks for wide-character strings are not implemented yet.
2582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  testPrintf("%ls", 1, 0);
259996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov}
260