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 }