modernc.org/ccgo/v3@v3.16.14/lib/testdata/gcc-9.1.0/gcc/testsuite/gcc.c-torture/execute/builtins/vsnprintf-chk.c (about)

     1  /* Copyright (C) 2004, 2005  Free Software Foundation.
     2  
     3     Ensure builtin __vsnprintf_chk performs correctly.  */
     4  
     5  #include <stdarg.h>
     6  
     7  extern void abort (void);
     8  typedef __SIZE_TYPE__ size_t;
     9  extern size_t strlen(const char *);
    10  extern void *memcpy (void *, const void *, size_t);
    11  extern char *strcpy (char *, const char *);
    12  extern int memcmp (const void *, const void *, size_t);
    13  extern void *memset (void *, int, size_t);
    14  extern int vsnprintf (char *, size_t, const char *, va_list);
    15  
    16  #include "chk.h"
    17  
    18  const char s1[] = "123";
    19  char p[32] = "";
    20  char *s2 = "defg";
    21  char *s3 = "FGH";
    22  char *s4;
    23  size_t l1 = 1;
    24  static char buffer[32];
    25  char * volatile ptr = "barf";  /* prevent constant propagation to happen when whole program assumptions are made.  */
    26  
    27  int
    28  __attribute__((noinline))
    29  test1_sub (int i, ...)
    30  {
    31    int ret = 0;
    32    va_list ap;
    33    va_start (ap, i);
    34    switch (i)
    35      {
    36      case 0:
    37        vsnprintf (buffer, 4, "foo", ap);
    38        break;
    39      case 1:
    40        ret = vsnprintf (buffer, 4, "foo bar", ap);
    41        break;
    42      case 2:
    43        vsnprintf (buffer, 32, "%s", ap);
    44        break;
    45      case 3:
    46        ret = vsnprintf (buffer, 21, "%s", ap);
    47        break;
    48      case 4:
    49        ret = vsnprintf (buffer, 4, "%d%d%d", ap);
    50        break;
    51      case 5:
    52        ret = vsnprintf (buffer, 32, "%d%d%d", ap);
    53        break;
    54      case 6:
    55        ret = vsnprintf (buffer, strlen (ptr) + 1, "%s", ap);
    56        break;
    57      case 7:
    58        vsnprintf (buffer, l1 + 31, "%d - %c", ap);
    59        break;
    60      case 8:
    61        vsnprintf (s4, l1 + 6, "%d - %c", ap);
    62        break;
    63      }
    64    va_end (ap);
    65    return ret;
    66  }
    67  
    68  void
    69  __attribute__((noinline))
    70  test1 (void)
    71  {
    72    chk_calls = 0;
    73    /* vsnprintf_disallowed = 1; */
    74  
    75    memset (buffer, 'A', 32);
    76    test1_sub (0);
    77    if (memcmp (buffer, "foo", 4) || buffer[4] != 'A')
    78      abort ();
    79  
    80    memset (buffer, 'A', 32);
    81    if (test1_sub (1) != 7)
    82      abort ();
    83    if (memcmp (buffer, "foo", 4) || buffer[4] != 'A')
    84      abort ();
    85  
    86    vsnprintf_disallowed = 0;
    87  
    88    memset (buffer, 'A', 32);
    89    test1_sub (2, "bar");
    90    if (memcmp (buffer, "bar", 4) || buffer[4] != 'A')
    91      abort ();
    92  
    93    memset (buffer, 'A', 32);
    94    if (test1_sub (3, "bar") != 3)
    95      abort ();
    96    if (memcmp (buffer, "bar", 4) || buffer[4] != 'A')
    97      abort ();
    98  
    99    memset (buffer, 'A', 32);
   100    if (test1_sub (4, (int) l1, (int) l1 + 1, (int) l1 + 12) != 4)
   101      abort ();
   102    if (memcmp (buffer, "121", 4) || buffer[4] != 'A')
   103      abort ();
   104  
   105    memset (buffer, 'A', 32);
   106    if (test1_sub (5, (int) l1, (int) l1 + 1, (int) l1 + 12) != 4)
   107      abort ();
   108    if (memcmp (buffer, "1213", 5) || buffer[5] != 'A')
   109      abort ();
   110  
   111    if (chk_calls)
   112      abort ();
   113  
   114    memset (buffer, 'A', 32);
   115    test1_sub (6, ptr);
   116    if (memcmp (buffer, "barf", 5) || buffer[5] != 'A')
   117      abort ();
   118  
   119    memset (buffer, 'A', 32);
   120    test1_sub (7, (int) l1 + 27, *ptr);
   121    if (memcmp (buffer, "28 - b\0AAAAA", 12))
   122      abort ();
   123  
   124    if (chk_calls != 2)
   125      abort ();
   126    chk_calls = 0;
   127  
   128    memset (s4, 'A', 32);
   129    test1_sub (8, (int) l1 - 17, ptr[1]);
   130    if (memcmp (s4, "-16 - \0AAA", 10))
   131      abort ();
   132    if (chk_calls)
   133      abort ();
   134  }
   135  
   136  void
   137  __attribute__((noinline))
   138  test2_sub (int i, ...)
   139  {
   140    va_list ap;
   141    struct A { char buf1[10]; char buf2[10]; } a;
   142    char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4];
   143    char buf3[20];
   144    int j;
   145  
   146    va_start (ap, i);
   147    /* The following calls should do runtime checking
   148       - length is not known, but destination is.  */
   149    switch (i)
   150      {
   151      case 0:
   152        vsnprintf (a.buf1 + 2, l1, "%s", ap);
   153        break;
   154      case 1:
   155        vsnprintf (r, l1 + 4, "%s%c", ap);
   156        break;
   157      case 2:
   158        r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   159        vsnprintf (r, strlen (s2) - 2, "%c %s", ap);
   160        break;
   161      case 3:
   162        r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   163        vsnprintf (r + 2, l1, s3 + 3, ap);
   164        break;
   165      case 4:
   166      case 7:
   167        r = buf3;
   168        for (j = 0; j < 4; ++j)
   169  	{
   170  	  if (j == l1 - 1)
   171  	    r = &a.buf1[1];
   172  	  else if (j == l1)
   173  	    r = &a.buf2[7];
   174  	  else if (j == l1 + 1)
   175  	    r = &buf3[5];
   176  	  else if (j == l1 + 2)
   177  	    r = &a.buf1[9];
   178  	}
   179        if (i == 4)
   180  	vsnprintf (r, l1, s2 + 4, ap);
   181        else
   182  	vsnprintf (r, 1, "a", ap);
   183        break;
   184      case 5:
   185        r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   186        vsnprintf (r, l1 + 3, "%s", ap);
   187        break;
   188      case 6:
   189        vsnprintf (a.buf1 + 2, 4, "", ap);
   190        break;
   191      case 8:
   192        vsnprintf (s4, 3, "%s %d", ap);
   193        break;
   194      }
   195    va_end (ap);
   196  }
   197  
   198  /* Test whether compile time checking is done where it should
   199     and so is runtime object size checking.  */
   200  void
   201  __attribute__((noinline))
   202  test2 (void)
   203  {
   204    /* The following calls should do runtime checking
   205       - length is not known, but destination is.  */
   206    chk_calls = 0;
   207    test2_sub (0, s3 + 3);
   208    test2_sub (1, s3 + 3, s3[3]);
   209    test2_sub (2, s2[2], s2 + 4);
   210    test2_sub (3);
   211    test2_sub (4);
   212    test2_sub (5, s1 + 1);
   213    if (chk_calls != 6)
   214      abort ();
   215  
   216    /* Following have known destination and known source length,
   217       so if optimizing certainly shouldn't result in the checking
   218       variants.  */
   219    chk_calls = 0;
   220    /* vsnprintf_disallowed = 1; */
   221    test2_sub (6);
   222    test2_sub (7);
   223    vsnprintf_disallowed = 0;
   224    /* Unknown destination and source, no checking.  */
   225    test2_sub (8, s3, 0);
   226    if (chk_calls)
   227      abort ();
   228  }
   229  
   230  void
   231  __attribute__((noinline))
   232  test3_sub (int i, ...)
   233  {
   234    va_list ap;
   235    struct A { char buf1[10]; char buf2[10]; } a;
   236    char buf3[20];
   237  
   238    va_start (ap, i);
   239    /* The following calls should do runtime checking
   240       - source length is not known, but destination is.  */
   241    switch (i)
   242      {
   243      case 0:
   244        vsnprintf (&a.buf2[9], l1 + 1, "%c%s", ap);
   245        break;
   246      case 1:
   247        vsnprintf (&a.buf2[7], l1 + 30, "%s%c", ap);
   248        break;
   249      case 2:
   250        vsnprintf (&a.buf2[7], l1 + 3, "%d", ap);
   251        break;
   252      case 3:
   253        vsnprintf (&buf3[17], l1 + 3, "%s", ap);
   254        break;
   255      case 4:
   256        vsnprintf (&buf3[19], 2, "a", ap);
   257        break;
   258      case 5:
   259        vsnprintf (&buf3[16], 5, "a", ap);
   260        break;
   261      }
   262    va_end (ap);
   263  }
   264  
   265  /* Test whether runtime and/or compile time checking catches
   266     buffer overflows.  */
   267  void
   268  __attribute__((noinline))
   269  test3 (void)
   270  {
   271    chk_fail_allowed = 1;
   272    /* Runtime checks.  */
   273    if (__builtin_setjmp (chk_fail_buf) == 0)
   274      {
   275        test3_sub (0, s2[3], s2 + 4);
   276        abort ();
   277      }
   278    if (__builtin_setjmp (chk_fail_buf) == 0)
   279      {
   280        test3_sub (1, s3 + strlen (s3) - 2, *s3);
   281        abort ();
   282      }
   283    if (__builtin_setjmp (chk_fail_buf) == 0)
   284      {
   285        test3_sub (2, (int) l1 + 9999);
   286        abort ();
   287      }
   288    if (__builtin_setjmp (chk_fail_buf) == 0)
   289      {
   290        test3_sub (3, "abc");
   291        abort ();
   292      }
   293    /* This should be detectable at compile time already.  */
   294    if (__builtin_setjmp (chk_fail_buf) == 0)
   295      {
   296        test3_sub (4);
   297        abort ();
   298      }
   299    if (__builtin_setjmp (chk_fail_buf) == 0)
   300      {
   301        test3_sub (5);
   302        abort ();
   303      }
   304    chk_fail_allowed = 0;
   305  }
   306  
   307  void
   308  main_test (void)
   309  {
   310  #ifndef __OPTIMIZE__
   311    /* Object size checking is only intended for -O[s123].  */
   312    return;
   313  #endif
   314    __asm ("" : "=r" (s2) : "0" (s2));
   315    __asm ("" : "=r" (s3) : "0" (s3));
   316    __asm ("" : "=r" (l1) : "0" (l1));
   317    s4 = p;
   318    test1 ();
   319    test2 ();
   320    test3 ();
   321  }