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

     1  /* Copyright (C) 2004, 2005  Free Software Foundation.
     2  
     3     Ensure builtin __sprintf_chk performs correctly.  */
     4  
     5  extern void abort (void);
     6  typedef __SIZE_TYPE__ size_t;
     7  extern size_t strlen(const char *);
     8  extern void *memcpy (void *, const void *, size_t);
     9  extern char *strcpy (char *, const char *);
    10  extern int memcmp (const void *, const void *, size_t);
    11  extern void *memset (void *, int, size_t);
    12  extern int sprintf (char *, const char *, ...);
    13  
    14  #include "chk.h"
    15  
    16  LOCAL const char s1[] = "123";
    17  char p[32] = "";
    18  char *s2 = "defg";
    19  char *s3 = "FGH";
    20  char *s4;
    21  size_t l1 = 1;
    22  static char buffer[32];
    23  char * volatile ptr = "barf"; /* prevent constant propagation to happen when whole program assumptions are made.  */
    24  
    25  void
    26  __attribute__((noinline))
    27  test1 (void)
    28  {
    29    chk_calls = 0;
    30    sprintf_disallowed = 1;
    31  
    32    memset (buffer, 'A', 32);
    33    sprintf (buffer, "foo");
    34    if (memcmp (buffer, "foo", 4) || buffer[4] != 'A')
    35      abort ();
    36  
    37    memset (buffer, 'A', 32);
    38    if (sprintf (buffer, "foo") != 3)
    39      abort ();
    40    if (memcmp (buffer, "foo", 4) || buffer[4] != 'A')
    41      abort ();
    42  
    43    memset (buffer, 'A', 32);
    44    sprintf (buffer, "%s", "bar");
    45    if (memcmp (buffer, "bar", 4) || buffer[4] != 'A')
    46      abort ();
    47  
    48    memset (buffer, 'A', 32);
    49    if (sprintf (buffer, "%s", "bar") != 3)
    50      abort ();
    51    if (memcmp (buffer, "bar", 4) || buffer[4] != 'A')
    52      abort ();
    53  
    54    if (chk_calls)
    55      abort ();
    56    sprintf_disallowed = 0;
    57  
    58    memset (buffer, 'A', 32);
    59    sprintf (buffer, "%s", ptr);
    60    if (memcmp (buffer, "barf", 5) || buffer[5] != 'A')
    61      abort ();
    62  
    63    memset (buffer, 'A', 32);
    64    sprintf (buffer, "%d - %c", (int) l1 + 27, *ptr);
    65    if (memcmp (buffer, "28 - b\0AAAAA", 12))
    66      abort ();
    67  
    68    if (chk_calls != 2)
    69      abort ();
    70    chk_calls = 0;
    71  
    72    sprintf (s4, "%d - %c", (int) l1 - 17, ptr[1]);
    73    if (memcmp (s4, "-16 - a", 8))
    74      abort ();
    75    if (chk_calls)
    76      abort ();
    77  }
    78  
    79  /* Test whether compile time checking is done where it should
    80     and so is runtime object size checking.  */
    81  void
    82  __attribute__((noinline))
    83  test2 (void)
    84  {
    85    struct A { char buf1[10]; char buf2[10]; } a;
    86    char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4];
    87    char buf3[20];
    88    int i;
    89  
    90    /* The following calls should do runtime checking
    91       - source length is not known, but destination is.  */
    92    chk_calls = 0;
    93    sprintf (a.buf1 + 2, "%s", s3 + 3);
    94    sprintf (r, "%s%c", s3 + 3, s3[3]);
    95    r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
    96    sprintf (r, "%c %s", s2[2], s2 + 4);
    97    sprintf (r + 2, s3 + 3);
    98    r = buf3;
    99    for (i = 0; i < 4; ++i)
   100      {
   101        if (i == l1 - 1)
   102  	r = &a.buf1[1];
   103        else if (i == l1)
   104  	r = &a.buf2[7];
   105        else if (i == l1 + 1)
   106  	r = &buf3[5];
   107        else if (i == l1 + 2)
   108  	r = &a.buf1[9];
   109      }
   110    sprintf (r, s2 + 4);
   111    if (chk_calls != 5)
   112      abort ();
   113  
   114    /* Following have known destination and known source length,
   115       so if optimizing certainly shouldn't result in the checking
   116       variants.  */
   117    chk_calls = 0;
   118    sprintf_disallowed = 1;
   119    sprintf (a.buf1 + 2, "");
   120    sprintf (r, "a");
   121    r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   122    sprintf (r, "%s", s1 + 1);
   123    r = buf3;
   124    for (i = 0; i < 4; ++i)
   125      {
   126        if (i == l1 - 1)
   127  	r = &a.buf1[1];
   128        else if (i == l1)
   129  	r = &a.buf2[7];
   130        else if (i == l1 + 1)
   131  	r = &buf3[5];
   132        else if (i == l1 + 2)
   133  	r = &a.buf1[9];
   134      }
   135    sprintf (r, "%s", "");
   136    sprintf_disallowed = 0;
   137    /* Unknown destination and source, no checking.  */
   138    sprintf (s4, "%s %d", s3, 0);
   139    if (chk_calls)
   140      abort ();
   141  }
   142  
   143  /* Test whether runtime and/or compile time checking catches
   144     buffer overflows.  */
   145  void
   146  __attribute__((noinline))
   147  test3 (void)
   148  {
   149    struct A { char buf1[10]; char buf2[10]; } a;
   150    char buf3[20];
   151  
   152    chk_fail_allowed = 1;
   153    /* Runtime checks.  */
   154    if (__builtin_setjmp (chk_fail_buf) == 0)
   155      {
   156        sprintf (&a.buf2[9], "%c%s", s2[3], s2 + 4);
   157        abort ();
   158      }
   159    if (__builtin_setjmp (chk_fail_buf) == 0)
   160      {
   161        sprintf (&a.buf2[7], "%s%c", s3 + strlen (s3) - 2, *s3);
   162        abort ();
   163      }
   164    if (__builtin_setjmp (chk_fail_buf) == 0)
   165      {
   166        sprintf (&a.buf2[7], "%d", (int) l1 + 9999);
   167        abort ();
   168      }
   169    /* This should be detectable at compile time already.  */
   170    if (__builtin_setjmp (chk_fail_buf) == 0)
   171      {
   172        sprintf (&buf3[19], "a");
   173        abort ();
   174      }
   175    if (__builtin_setjmp (chk_fail_buf) == 0)
   176      {
   177        sprintf (&buf3[17], "%s", "abc");
   178        abort ();
   179      }
   180    chk_fail_allowed = 0;
   181  }
   182  
   183  void
   184  main_test (void)
   185  {
   186  #ifndef __OPTIMIZE__
   187    /* Object size checking is only intended for -O[s123].  */
   188    return;
   189  #endif
   190    __asm ("" : "=r" (s2) : "0" (s2));
   191    __asm ("" : "=r" (s3) : "0" (s3));
   192    __asm ("" : "=r" (l1) : "0" (l1));
   193    s4 = p;
   194    test1 ();
   195    test2 ();
   196    test3 ();
   197  }