Home | History | Annotate | Download | only in tests
      1 //===-- sanitizer_format_interceptor_test.cc ------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Tests for *scanf interceptors implementation in sanitizer_common.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 #include <algorithm>
     14 #include <vector>
     15 
     16 #include "interception/interception.h"
     17 #include "sanitizer_test_utils.h"
     18 #include "sanitizer_common/sanitizer_libc.h"
     19 #include "sanitizer_common/sanitizer_common.h"
     20 #include "gtest/gtest.h"
     21 
     22 using namespace __sanitizer;
     23 
     24 #define COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)                    \
     25   do {                                                                         \
     26     ((std::vector<unsigned> *)ctx)->push_back(size);                           \
     27     ptr = ptr;                                                                 \
     28   } while (0)
     29 
     30 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size)                          \
     31   COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)
     32 
     33 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)                         \
     34   COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)
     35 
     36 #define SANITIZER_INTERCEPT_PRINTF 1
     37 #include "sanitizer_common/sanitizer_common_interceptors_format.inc"
     38 
     39 static const unsigned I = sizeof(int);
     40 static const unsigned L = sizeof(long);
     41 static const unsigned LL = sizeof(long long);
     42 static const unsigned S = sizeof(short);
     43 static const unsigned C = sizeof(char);
     44 static const unsigned LC = sizeof(wchar_t);
     45 static const unsigned D = sizeof(double);
     46 static const unsigned LD = sizeof(long double);
     47 static const unsigned F = sizeof(float);
     48 static const unsigned P = sizeof(char *);
     49 
     50 static void verifyFormatResults(const char *format, unsigned n,
     51                                 const std::vector<unsigned> &computed_sizes,
     52                                 va_list expected_sizes) {
     53   // "+ 1" because of format string
     54   ASSERT_EQ(n + 1,
     55             computed_sizes.size()) << "Unexpected number of format arguments: '"
     56                                    << format << "'";
     57   for (unsigned i = 0; i < n; ++i)
     58     EXPECT_EQ(va_arg(expected_sizes, unsigned), computed_sizes[i + 1])
     59         << "Unexpect write size for argument " << i << ", format string '"
     60         << format << "'";
     61 }
     62 
     63 static const char test_buf[] = "Test string.";
     64 static const size_t test_buf_size = sizeof(test_buf);
     65 
     66 static const unsigned SCANF_ARGS_MAX = 16;
     67 
     68 static void testScanf3(void *ctx, int result, bool allowGnuMalloc,
     69                        const char *format, ...) {
     70   va_list ap;
     71   va_start(ap, format);
     72   scanf_common(ctx, result, allowGnuMalloc, format, ap);
     73   va_end(ap);
     74 }
     75 
     76 static void testScanf2(const char *format, int scanf_result,
     77                        bool allowGnuMalloc, unsigned n,
     78                        va_list expected_sizes) {
     79   std::vector<unsigned> scanf_sizes;
     80   // 16 args should be enough.
     81   testScanf3((void *)&scanf_sizes, scanf_result, allowGnuMalloc, format,
     82              test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
     83              test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
     84              test_buf, test_buf, test_buf, test_buf);
     85   verifyFormatResults(format, n, scanf_sizes, expected_sizes);
     86 }
     87 
     88 static void testScanf(const char *format, unsigned n, ...) {
     89   va_list ap;
     90   va_start(ap, n);
     91   testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ true, n, ap);
     92   va_end(ap);
     93 }
     94 
     95 static void testScanfPartial(const char *format, int scanf_result, unsigned n,
     96                              ...) {
     97   va_list ap;
     98   va_start(ap, n);
     99   testScanf2(format, scanf_result, /* allowGnuMalloc */ true,  n, ap);
    100   va_end(ap);
    101 }
    102 
    103 static void testScanfNoGnuMalloc(const char *format, unsigned n, ...) {
    104   va_list ap;
    105   va_start(ap, n);
    106   testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ false, n, ap);
    107   va_end(ap);
    108 }
    109 
    110 TEST(SanitizerCommonInterceptors, Scanf) {
    111   testScanf("%d", 1, I);
    112   testScanf("%d%d%d", 3, I, I, I);
    113   testScanf("ab%u%dc", 2, I, I);
    114   testScanf("%ld", 1, L);
    115   testScanf("%llu", 1, LL);
    116   testScanf("%qd", 1, LL);
    117   testScanf("a %hd%hhx", 2, S, C);
    118   testScanf("%c", 1, C);
    119   testScanf("%lc", 1, LC);
    120 
    121   testScanf("%%", 0);
    122   testScanf("a%%", 0);
    123   testScanf("a%%b", 0);
    124   testScanf("a%%%%b", 0);
    125   testScanf("a%%b%%", 0);
    126   testScanf("a%%%%%%b", 0);
    127   testScanf("a%%%%%b", 0);
    128   testScanf("a%%%%%f", 1, F);
    129   testScanf("a%%%lxb", 1, L);
    130   testScanf("a%lf%%%lxb", 2, D, L);
    131   testScanf("%nf", 1, I);
    132 
    133   testScanf("%10s", 1, 11);
    134   testScanf("%10c", 1, 10);
    135   testScanf("%10ls", 1, 11 * LC);
    136   testScanf("%10lc", 1, 10 * LC);
    137   testScanf("%%10s", 0);
    138   testScanf("%*10s", 0);
    139   testScanf("%*d", 0);
    140 
    141   testScanf("%4d%8f%c", 3, I, F, C);
    142   testScanf("%s%d", 2, test_buf_size, I);
    143   testScanf("%[abc]", 1, test_buf_size);
    144   testScanf("%4[bcdef]", 1, 5);
    145   testScanf("%[]]", 1, test_buf_size);
    146   testScanf("%8[^]%d0-9-]%c", 2, 9, C);
    147 
    148   testScanf("%*[^:]%n:%d:%1[ ]%n", 4, I, I, 2, I);
    149 
    150   testScanf("%*d%u", 1, I);
    151 
    152   testScanf("%c%d", 2, C, I);
    153   testScanf("%A%lf", 2, F, D);
    154 
    155   testScanf("%ms %Lf", 2, P, LD);
    156   testScanf("s%Las", 1, LD);
    157   testScanf("%ar", 1, F);
    158 
    159   // In the cases with std::min below the format spec can be interpreted as
    160   // either floating-something, or (GNU extension) callee-allocated string.
    161   // Our conservative implementation reports one of the two possibilities with
    162   // the least store range.
    163   testScanf("%a[", 0);
    164   testScanf("%a[]", 0);
    165   testScanf("%a[]]", 1, std::min(F, P));
    166   testScanf("%a[abc]", 1, std::min(F, P));
    167   testScanf("%a[^abc]", 1, std::min(F, P));
    168   testScanf("%a[ab%c] %d", 0);
    169   testScanf("%a[^ab%c] %d", 0);
    170   testScanf("%as", 1, std::min(F, P));
    171   testScanf("%aS", 1, std::min(F, P));
    172   testScanf("%a13S", 1, std::min(F, P));
    173   testScanf("%alS", 1, std::min(F, P));
    174 
    175   testScanfNoGnuMalloc("s%Las", 1, LD);
    176   testScanfNoGnuMalloc("%ar", 1, F);
    177   testScanfNoGnuMalloc("%a[", 1, F);
    178   testScanfNoGnuMalloc("%a[]", 1, F);
    179   testScanfNoGnuMalloc("%a[]]", 1, F);
    180   testScanfNoGnuMalloc("%a[abc]", 1, F);
    181   testScanfNoGnuMalloc("%a[^abc]", 1, F);
    182   testScanfNoGnuMalloc("%a[ab%c] %d", 3, F, C, I);
    183   testScanfNoGnuMalloc("%a[^ab%c] %d", 3, F, C, I);
    184   testScanfNoGnuMalloc("%as", 1, F);
    185   testScanfNoGnuMalloc("%aS", 1, F);
    186   testScanfNoGnuMalloc("%a13S", 1, F);
    187   testScanfNoGnuMalloc("%alS", 1, F);
    188 
    189   testScanf("%5$d", 0);
    190   testScanf("%md", 0);
    191   testScanf("%m10s", 0);
    192 
    193   testScanfPartial("%d%d%d%d //1\n", 1, 1, I);
    194   testScanfPartial("%d%d%d%d //2\n", 2, 2, I, I);
    195   testScanfPartial("%d%d%d%d //3\n", 3, 3, I, I, I);
    196   testScanfPartial("%d%d%d%d //4\n", 4, 4, I, I, I, I);
    197 
    198   testScanfPartial("%d%n%n%d //1\n", 1, 3, I, I, I);
    199   testScanfPartial("%d%n%n%d //2\n", 2, 4, I, I, I, I);
    200 
    201   testScanfPartial("%d%n%n%d %s %s", 3, 5, I, I, I, I, test_buf_size);
    202   testScanfPartial("%d%n%n%d %s %s", 4, 6, I, I, I, I, test_buf_size,
    203                    test_buf_size);
    204 }
    205 
    206 static void testPrintf3(void *ctx, const char *format, ...) {
    207   va_list ap;
    208   va_start(ap, format);
    209   printf_common(ctx, format, ap);
    210   va_end(ap);
    211 }
    212 
    213 static void testPrintf2(const char *format, unsigned n,
    214                        va_list expected_sizes) {
    215   std::vector<unsigned> printf_sizes;
    216   // 16 args should be enough.
    217   testPrintf3((void *)&printf_sizes, format,
    218              test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
    219              test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
    220              test_buf, test_buf, test_buf, test_buf);
    221   verifyFormatResults(format, n, printf_sizes, expected_sizes);
    222 }
    223 
    224 static void testPrintf(const char *format, unsigned n, ...) {
    225   va_list ap;
    226   va_start(ap, n);
    227   testPrintf2(format, n, ap);
    228   va_end(ap);
    229 }
    230 
    231 TEST(SanitizerCommonInterceptors, Printf) {
    232   // Only test functionality which differs from scanf
    233 
    234   // Indexed arguments
    235   testPrintf("%5$d", 0);
    236   testPrintf("%.*5$d", 0);
    237 
    238   // errno
    239   testPrintf("%0-m", 0);
    240 
    241   // Dynamic width
    242   testPrintf("%*n", 1, I);
    243   testPrintf("%*.10n", 1, I);
    244 
    245   // Precision
    246   testPrintf("%10.10n", 1, I);
    247   testPrintf("%.3s", 1, 3);
    248   testPrintf("%.20s", 1, test_buf_size);
    249 
    250   // Dynamic precision
    251   testPrintf("%.*n", 1, I);
    252   testPrintf("%10.*n", 1, I);
    253 
    254   // Dynamic precision for strings is not implemented yet.
    255   testPrintf("%.*s", 1, 0);
    256 
    257   // Checks for wide-character strings are not implemented yet.
    258   testPrintf("%ls", 1, 0);
    259 }
    260