Home | History | Annotate | Download | only in tests
      1 //===-- sanitizer_scanf_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 <vector>
     14 
     15 #include "interception/interception.h"
     16 #include "sanitizer_test_utils.h"
     17 #include "sanitizer_common/sanitizer_libc.h"
     18 #include "gtest/gtest.h"
     19 
     20 using namespace __sanitizer;
     21 
     22 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)                         \
     23   ((std::vector<unsigned> *)ctx)->push_back(size)
     24 
     25 #include "sanitizer_common/sanitizer_common_interceptors_scanf.inc"
     26 
     27 static const char scanf_buf[] = "Test string.";
     28 static size_t scanf_buf_size = sizeof(scanf_buf);
     29 static const unsigned SCANF_ARGS_MAX = 16;
     30 
     31 static void testScanf3(void *ctx, int result, bool allowGnuMalloc,
     32                        const char *format, ...) {
     33   va_list ap;
     34   va_start(ap, format);
     35   scanf_common(ctx, result, allowGnuMalloc, format, ap);
     36   va_end(ap);
     37 }
     38 
     39 static void testScanf2(const char *format, int scanf_result,
     40                        bool allowGnuMalloc, unsigned n,
     41                        va_list expected_sizes) {
     42   std::vector<unsigned> scanf_sizes;
     43   // 16 args should be enough.
     44   testScanf3((void *)&scanf_sizes, scanf_result, allowGnuMalloc, format,
     45              scanf_buf, scanf_buf, scanf_buf, scanf_buf, scanf_buf, scanf_buf,
     46              scanf_buf, scanf_buf, scanf_buf, scanf_buf, scanf_buf, scanf_buf,
     47              scanf_buf, scanf_buf, scanf_buf, scanf_buf);
     48   ASSERT_EQ(n, scanf_sizes.size()) << "Unexpected number of format arguments: '"
     49                                    << format << "'";
     50   for (unsigned i = 0; i < n; ++i)
     51     EXPECT_EQ(va_arg(expected_sizes, unsigned), scanf_sizes[i])
     52         << "Unexpect write size for argument " << i << ", format string '"
     53         << format << "'";
     54 }
     55 
     56 static void testScanf(const char *format, unsigned n, ...) {
     57   va_list ap;
     58   va_start(ap, n);
     59   testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ true, n, ap);
     60   va_end(ap);
     61 }
     62 
     63 static void testScanfPartial(const char *format, int scanf_result, unsigned n,
     64                              ...) {
     65   va_list ap;
     66   va_start(ap, n);
     67   testScanf2(format, scanf_result, /* allowGnuMalloc */ true,  n, ap);
     68   va_end(ap);
     69 }
     70 
     71 static void testScanfNoGnuMalloc(const char *format, unsigned n, ...) {
     72   va_list ap;
     73   va_start(ap, n);
     74   testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ false, n, ap);
     75   va_end(ap);
     76 }
     77 
     78 TEST(SanitizerCommonInterceptors, Scanf) {
     79   const unsigned I = sizeof(int);          // NOLINT
     80   const unsigned L = sizeof(long);         // NOLINT
     81   const unsigned LL = sizeof(long long);   // NOLINT
     82   const unsigned S = sizeof(short);        // NOLINT
     83   const unsigned C = sizeof(char);         // NOLINT
     84   const unsigned D = sizeof(double);       // NOLINT
     85   const unsigned LD = sizeof(long double); // NOLINT
     86   const unsigned F = sizeof(float);        // NOLINT
     87   const unsigned P = sizeof(char *);       // NOLINT
     88 
     89   testScanf("%d", 1, I);
     90   testScanf("%d%d%d", 3, I, I, I);
     91   testScanf("ab%u%dc", 2, I, I);
     92   testScanf("%ld", 1, L);
     93   testScanf("%llu", 1, LL);
     94   testScanf("a %hd%hhx", 2, S, C);
     95   testScanf("%c", 1, C);
     96 
     97   testScanf("%%", 0);
     98   testScanf("a%%", 0);
     99   testScanf("a%%b", 0);
    100   testScanf("a%%%%b", 0);
    101   testScanf("a%%b%%", 0);
    102   testScanf("a%%%%%%b", 0);
    103   testScanf("a%%%%%b", 0);
    104   testScanf("a%%%%%f", 1, F);
    105   testScanf("a%%%lxb", 1, L);
    106   testScanf("a%lf%%%lxb", 2, D, L);
    107   testScanf("%nf", 1, I);
    108 
    109   testScanf("%10s", 1, 11);
    110   testScanf("%10c", 1, 10);
    111   testScanf("%%10s", 0);
    112   testScanf("%*10s", 0);
    113   testScanf("%*d", 0);
    114 
    115   testScanf("%4d%8f%c", 3, I, F, C);
    116   testScanf("%s%d", 2, scanf_buf_size, I);
    117   testScanf("%[abc]", 1, scanf_buf_size);
    118   testScanf("%4[bcdef]", 1, 5);
    119   testScanf("%[]]", 1, scanf_buf_size);
    120   testScanf("%8[^]%d0-9-]%c", 2, 9, C);
    121 
    122   testScanf("%*[^:]%n:%d:%1[ ]%n", 4, I, I, 2, I);
    123 
    124   testScanf("%*d%u", 1, I);
    125 
    126   testScanf("%c%d", 2, C, I);
    127   testScanf("%A%lf", 2, F, D);
    128 
    129   testScanf("%ms %Lf", 2, P, LD);
    130   testScanf("s%Las", 1, LD);
    131   testScanf("%ar", 1, F);
    132 
    133   // In the cases with std::min below the format spec can be interpreted as
    134   // either floating-something, or (GNU extension) callee-allocated string.
    135   // Our conservative implementation reports one of the two possibilities with
    136   // the least store range.
    137   testScanf("%a[", 0);
    138   testScanf("%a[]", 0);
    139   testScanf("%a[]]", 1, std::min(F, P));
    140   testScanf("%a[abc]", 1, std::min(F, P));
    141   testScanf("%a[^abc]", 1, std::min(F, P));
    142   testScanf("%a[ab%c] %d", 0);
    143   testScanf("%a[^ab%c] %d", 0);
    144   testScanf("%as", 1, std::min(F, P));
    145   testScanf("%aS", 1, std::min(F, P));
    146   testScanf("%a13S", 1, std::min(F, P));
    147   testScanf("%alS", 1, std::min(F, P));
    148 
    149   testScanfNoGnuMalloc("s%Las", 1, LD);
    150   testScanfNoGnuMalloc("%ar", 1, F);
    151   testScanfNoGnuMalloc("%a[", 1, F);
    152   testScanfNoGnuMalloc("%a[]", 1, F);
    153   testScanfNoGnuMalloc("%a[]]", 1, F);
    154   testScanfNoGnuMalloc("%a[abc]", 1, F);
    155   testScanfNoGnuMalloc("%a[^abc]", 1, F);
    156   testScanfNoGnuMalloc("%a[ab%c] %d", 3, F, C, I);
    157   testScanfNoGnuMalloc("%a[^ab%c] %d", 3, F, C, I);
    158   testScanfNoGnuMalloc("%as", 1, F);
    159   testScanfNoGnuMalloc("%aS", 1, F);
    160   testScanfNoGnuMalloc("%a13S", 1, F);
    161   testScanfNoGnuMalloc("%alS", 1, F);
    162 
    163   testScanf("%5$d", 0);
    164   testScanf("%md", 0);
    165   testScanf("%m10s", 0);
    166 
    167   testScanfPartial("%d%d%d%d //1\n", 1, 1, I);
    168   testScanfPartial("%d%d%d%d //2\n", 2, 2, I, I);
    169   testScanfPartial("%d%d%d%d //3\n", 3, 3, I, I, I);
    170   testScanfPartial("%d%d%d%d //4\n", 4, 4, I, I, I, I);
    171 
    172   testScanfPartial("%d%n%n%d //1\n", 1, 1, I);
    173   testScanfPartial("%d%n%n%d //2\n", 2, 4, I, I, I, I);
    174 
    175   testScanfPartial("%d%n%n%d %s %s", 3, 5, I, I, I, I, scanf_buf_size);
    176   testScanfPartial("%d%n%n%d %s %s", 4, 6, I, I, I, I, scanf_buf_size,
    177                    scanf_buf_size);
    178 }
    179