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