1 /* Copyright (C) 2004, 2005 Free Software Foundation.
3 Ensure builtin __vsnprintf_chk performs correctly. */
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);
18 const char s1
[] = "123";
24 static char buffer
[32];
28 __attribute__((noinline
))
29 test1_sub (int i
, ...)
37 vsnprintf (buffer
, 4, "foo", ap
);
40 ret
= vsnprintf (buffer
, 4, "foo bar", ap
);
43 vsnprintf (buffer
, 32, "%s", ap
);
46 ret
= vsnprintf (buffer
, 21, "%s", ap
);
49 ret
= vsnprintf (buffer
, 4, "%d%d%d", ap
);
52 ret
= vsnprintf (buffer
, 32, "%d%d%d", ap
);
55 ret
= vsnprintf (buffer
, strlen (ptr
) + 1, "%s", ap
);
58 vsnprintf (buffer
, l1
+ 31, "%d - %c", ap
);
61 vsnprintf (s4
, l1
+ 6, "%d - %c", ap
);
69 __attribute__((noinline
))
73 /* vsnprintf_disallowed = 1; */
75 memset (buffer
, 'A', 32);
77 if (memcmp (buffer
, "foo", 4) || buffer
[4] != 'A')
80 memset (buffer
, 'A', 32);
81 if (test1_sub (1) != 7)
83 if (memcmp (buffer
, "foo", 4) || buffer
[4] != 'A')
86 vsnprintf_disallowed
= 0;
88 memset (buffer
, 'A', 32);
90 if (memcmp (buffer
, "bar", 4) || buffer
[4] != 'A')
93 memset (buffer
, 'A', 32);
94 if (test1_sub (3, "bar") != 3)
96 if (memcmp (buffer
, "bar", 4) || buffer
[4] != 'A')
99 memset (buffer
, 'A', 32);
100 if (test1_sub (4, (int) l1
, (int) l1
+ 1, (int) l1
+ 12) != 4)
102 if (memcmp (buffer
, "121", 4) || buffer
[4] != 'A')
105 memset (buffer
, 'A', 32);
106 if (test1_sub (5, (int) l1
, (int) l1
+ 1, (int) l1
+ 12) != 4)
108 if (memcmp (buffer
, "1213", 5) || buffer
[5] != 'A')
114 memset (buffer
, 'A', 32);
116 if (memcmp (buffer
, "barf", 5) || buffer
[5] != 'A')
119 memset (buffer
, 'A', 32);
120 test1_sub (7, (int) l1
+ 27, *ptr
);
121 if (memcmp (buffer
, "28 - b\0AAAAA", 12))
128 memset (s4
, 'A', 32);
129 test1_sub (8, (int) l1
- 17, ptr
[1]);
130 if (memcmp (s4
, "-16 - \0AAA", 10))
137 __attribute__((noinline
))
138 test2_sub (int i
, ...)
141 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
142 char *r
= l1
== 1 ? &a
.buf1
[5] : &a
.buf2
[4];
147 /* The following calls should do runtime checking
148 - length is not known, but destination is. */
152 vsnprintf (a
.buf1
+ 2, l1
, "%s", ap
);
155 vsnprintf (r
, l1
+ 4, "%s%c", ap
);
158 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
159 vsnprintf (r
, strlen (s2
) - 2, "%c %s", ap
);
162 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
163 vsnprintf (r
+ 2, l1
, s3
+ 3, ap
);
168 for (j
= 0; j
< 4; ++j
)
174 else if (j
== l1
+ 1)
176 else if (j
== l1
+ 2)
180 vsnprintf (r
, l1
, s2
+ 4, ap
);
182 vsnprintf (r
, 1, "a", ap
);
185 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
186 vsnprintf (r
, l1
+ 3, "%s", ap
);
189 vsnprintf (a
.buf1
+ 2, 4, "", ap
);
192 vsnprintf (s4
, 3, "%s %d", ap
);
198 /* Test whether compile time checking is done where it should
199 and so is runtime object size checking. */
201 __attribute__((noinline
))
204 /* The following calls should do runtime checking
205 - length is not known, but destination is. */
207 test2_sub (0, s3
+ 3);
208 test2_sub (1, s3
+ 3, s3
[3]);
209 test2_sub (2, s2
[2], s2
+ 4);
212 test2_sub (5, s1
+ 1);
216 /* Following have known destination and known source length,
217 so if optimizing certainly shouldn't result in the checking
220 /* vsnprintf_disallowed = 1; */
223 vsnprintf_disallowed
= 0;
224 /* Unknown destination and source, no checking. */
225 test2_sub (8, s3
, 0);
231 __attribute__((noinline
))
232 test3_sub (int i
, ...)
235 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
239 /* The following calls should do runtime checking
240 - source length is not known, but destination is. */
244 vsnprintf (&a
.buf2
[9], l1
+ 1, "%c%s", ap
);
247 vsnprintf (&a
.buf2
[7], l1
+ 30, "%s%c", ap
);
250 vsnprintf (&a
.buf2
[7], l1
+ 3, "%d", ap
);
253 vsnprintf (&buf3
[17], l1
+ 3, "%s", ap
);
256 vsnprintf (&buf3
[19], 2, "a", ap
);
259 vsnprintf (&buf3
[16], 5, "a", ap
);
265 /* Test whether runtime and/or compile time checking catches
268 __attribute__((noinline
))
271 chk_fail_allowed
= 1;
272 /* Runtime checks. */
273 if (__builtin_setjmp (chk_fail_buf
) == 0)
275 test3_sub (0, s2
[3], s2
+ 4);
278 if (__builtin_setjmp (chk_fail_buf
) == 0)
280 test3_sub (1, s3
+ strlen (s3
) - 2, *s3
);
283 if (__builtin_setjmp (chk_fail_buf
) == 0)
285 test3_sub (2, (int) l1
+ 9999);
288 if (__builtin_setjmp (chk_fail_buf
) == 0)
290 test3_sub (3, "abc");
293 /* This should be detectable at compile time already. */
294 if (__builtin_setjmp (chk_fail_buf
) == 0)
299 if (__builtin_setjmp (chk_fail_buf
) == 0)
304 chk_fail_allowed
= 0;
311 /* Object size checking is only intended for -O[s123]. */
314 __asm ("" : "=r" (s2
) : "0" (s2
));
315 __asm ("" : "=r" (s3
) : "0" (s3
));
316 __asm ("" : "=r" (l1
) : "0" (l1
));