improve out-of-bounds checking with GCC 10 attribute access [BZ #25219]
[glibc.git] / libio / bits / stdio2.h
blobff9202c2cbb2bc3e48c0a9f7d163c998a3b13608
1 /* Checking macros for stdio functions.
2 Copyright (C) 2004-2020 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #ifndef _BITS_STDIO2_H
20 #define _BITS_STDIO2_H 1
22 #ifndef _STDIO_H
23 # error "Never include <bits/stdio2.h> directly; use <stdio.h> instead."
24 #endif
26 extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen,
27 const char *__restrict __format, ...) __THROW
28 __attr_access ((__write_only__, 1, 3));
29 extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen,
30 const char *__restrict __format,
31 __gnuc_va_list __ap) __THROW
32 __attr_access ((__write_only__, 1, 3));
34 #ifdef __va_arg_pack
35 __fortify_function int
36 __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
38 return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
39 __bos (__s), __fmt, __va_arg_pack ());
41 #elif !defined __cplusplus
42 # define sprintf(str, ...) \
43 __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \
44 __VA_ARGS__)
45 #endif
47 __fortify_function int
48 __NTH (vsprintf (char *__restrict __s, const char *__restrict __fmt,
49 __gnuc_va_list __ap))
51 return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
52 __bos (__s), __fmt, __ap);
55 #if defined __USE_ISOC99 || defined __USE_UNIX98
57 extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag,
58 size_t __slen, const char *__restrict __format,
59 ...) __THROW
60 __attr_access ((__write_only__, 1, 2));
61 extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
62 size_t __slen, const char *__restrict __format,
63 __gnuc_va_list __ap) __THROW;
65 # ifdef __va_arg_pack
66 __fortify_function int
67 __NTH (snprintf (char *__restrict __s, size_t __n,
68 const char *__restrict __fmt, ...))
70 return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
71 __bos (__s), __fmt, __va_arg_pack ());
73 # elif !defined __cplusplus
74 # define snprintf(str, len, ...) \
75 __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
76 __VA_ARGS__)
77 # endif
79 __fortify_function int
80 __NTH (vsnprintf (char *__restrict __s, size_t __n,
81 const char *__restrict __fmt, __gnuc_va_list __ap))
83 return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
84 __bos (__s), __fmt, __ap);
87 #endif
89 #if __USE_FORTIFY_LEVEL > 1
91 extern int __fprintf_chk (FILE *__restrict __stream, int __flag,
92 const char *__restrict __format, ...);
93 extern int __printf_chk (int __flag, const char *__restrict __format, ...);
94 extern int __vfprintf_chk (FILE *__restrict __stream, int __flag,
95 const char *__restrict __format, __gnuc_va_list __ap);
96 extern int __vprintf_chk (int __flag, const char *__restrict __format,
97 __gnuc_va_list __ap);
99 # ifdef __va_arg_pack
100 __fortify_function int
101 fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...)
103 return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
104 __va_arg_pack ());
107 __fortify_function int
108 printf (const char *__restrict __fmt, ...)
110 return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
112 # elif !defined __cplusplus
113 # define printf(...) \
114 __printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
115 # define fprintf(stream, ...) \
116 __fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
117 # endif
119 __fortify_function int
120 vprintf (const char *__restrict __fmt, __gnuc_va_list __ap)
122 #ifdef __USE_EXTERN_INLINES
123 return __vfprintf_chk (stdout, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
124 #else
125 return __vprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap);
126 #endif
129 __fortify_function int
130 vfprintf (FILE *__restrict __stream,
131 const char *__restrict __fmt, __gnuc_va_list __ap)
133 return __vfprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
136 # ifdef __USE_XOPEN2K8
137 extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt,
138 ...) __attribute__ ((__format__ (__printf__, 3, 4)));
139 extern int __vdprintf_chk (int __fd, int __flag,
140 const char *__restrict __fmt, __gnuc_va_list __arg)
141 __attribute__ ((__format__ (__printf__, 3, 0)));
143 # ifdef __va_arg_pack
144 __fortify_function int
145 dprintf (int __fd, const char *__restrict __fmt, ...)
147 return __dprintf_chk (__fd, __USE_FORTIFY_LEVEL - 1, __fmt,
148 __va_arg_pack ());
150 # elif !defined __cplusplus
151 # define dprintf(fd, ...) \
152 __dprintf_chk (fd, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
153 # endif
155 __fortify_function int
156 vdprintf (int __fd, const char *__restrict __fmt, __gnuc_va_list __ap)
158 return __vdprintf_chk (__fd, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
160 # endif
162 # ifdef __USE_GNU
164 extern int __asprintf_chk (char **__restrict __ptr, int __flag,
165 const char *__restrict __fmt, ...)
166 __THROW __attribute__ ((__format__ (__printf__, 3, 4))) __wur;
167 extern int __vasprintf_chk (char **__restrict __ptr, int __flag,
168 const char *__restrict __fmt, __gnuc_va_list __arg)
169 __THROW __attribute__ ((__format__ (__printf__, 3, 0))) __wur;
170 extern int __obstack_printf_chk (struct obstack *__restrict __obstack,
171 int __flag, const char *__restrict __format,
172 ...)
173 __THROW __attribute__ ((__format__ (__printf__, 3, 4)));
174 extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack,
175 int __flag,
176 const char *__restrict __format,
177 __gnuc_va_list __args)
178 __THROW __attribute__ ((__format__ (__printf__, 3, 0)));
180 # ifdef __va_arg_pack
181 __fortify_function int
182 __NTH (asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...))
184 return __asprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt,
185 __va_arg_pack ());
188 __fortify_function int
189 __NTH (__asprintf (char **__restrict __ptr, const char *__restrict __fmt,
190 ...))
192 return __asprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt,
193 __va_arg_pack ());
196 __fortify_function int
197 __NTH (obstack_printf (struct obstack *__restrict __obstack,
198 const char *__restrict __fmt, ...))
200 return __obstack_printf_chk (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt,
201 __va_arg_pack ());
203 # elif !defined __cplusplus
204 # define asprintf(ptr, ...) \
205 __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
206 # define __asprintf(ptr, ...) \
207 __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
208 # define obstack_printf(obstack, ...) \
209 __obstack_printf_chk (obstack, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
210 # endif
212 __fortify_function int
213 __NTH (vasprintf (char **__restrict __ptr, const char *__restrict __fmt,
214 __gnuc_va_list __ap))
216 return __vasprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
219 __fortify_function int
220 __NTH (obstack_vprintf (struct obstack *__restrict __obstack,
221 const char *__restrict __fmt, __gnuc_va_list __ap))
223 return __obstack_vprintf_chk (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt,
224 __ap);
227 # endif
229 #endif
231 #if __GLIBC_USE (DEPRECATED_GETS)
232 extern char *__gets_chk (char *__str, size_t) __wur;
233 extern char *__REDIRECT (__gets_warn, (char *__str), gets)
234 __wur __warnattr ("please use fgets or getline instead, gets can't "
235 "specify buffer size");
237 __fortify_function __wur char *
238 gets (char *__str)
240 if (__bos (__str) != (size_t) -1)
241 return __gets_chk (__str, __bos (__str));
242 return __gets_warn (__str);
244 #endif
246 extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n,
247 FILE *__restrict __stream)
248 __wur __attr_access ((__write_only__, 1, 3));
249 extern char *__REDIRECT (__fgets_alias,
250 (char *__restrict __s, int __n,
251 FILE *__restrict __stream), fgets)
252 __wur __attr_access ((__write_only__, 1, 2));
253 extern char *__REDIRECT (__fgets_chk_warn,
254 (char *__restrict __s, size_t __size, int __n,
255 FILE *__restrict __stream), __fgets_chk)
256 __wur __warnattr ("fgets called with bigger size than length "
257 "of destination buffer");
259 __fortify_function __wur __attr_access ((__write_only__, 1, 2)) char *
260 fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
262 if (__bos (__s) != (size_t) -1)
264 if (!__builtin_constant_p (__n) || __n <= 0)
265 return __fgets_chk (__s, __bos (__s), __n, __stream);
267 if ((size_t) __n > __bos (__s))
268 return __fgets_chk_warn (__s, __bos (__s), __n, __stream);
270 return __fgets_alias (__s, __n, __stream);
273 extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen,
274 size_t __size, size_t __n,
275 FILE *__restrict __stream) __wur;
276 extern size_t __REDIRECT (__fread_alias,
277 (void *__restrict __ptr, size_t __size,
278 size_t __n, FILE *__restrict __stream),
279 fread) __wur;
280 extern size_t __REDIRECT (__fread_chk_warn,
281 (void *__restrict __ptr, size_t __ptrlen,
282 size_t __size, size_t __n,
283 FILE *__restrict __stream),
284 __fread_chk)
285 __wur __warnattr ("fread called with bigger size * nmemb than length "
286 "of destination buffer");
288 __fortify_function __wur size_t
289 fread (void *__restrict __ptr, size_t __size, size_t __n,
290 FILE *__restrict __stream)
292 if (__bos0 (__ptr) != (size_t) -1)
294 if (!__builtin_constant_p (__size)
295 || !__builtin_constant_p (__n)
296 || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)))
297 return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
299 if (__size * __n > __bos0 (__ptr))
300 return __fread_chk_warn (__ptr, __bos0 (__ptr), __size, __n, __stream);
302 return __fread_alias (__ptr, __size, __n, __stream);
305 #ifdef __USE_GNU
306 extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size,
307 int __n, FILE *__restrict __stream)
308 __wur __attr_access ((__write_only__, 1, 3));
309 extern char *__REDIRECT (__fgets_unlocked_alias,
310 (char *__restrict __s, int __n,
311 FILE *__restrict __stream), fgets_unlocked)
312 __wur __attr_access ((__write_only__, 1, 2));
313 extern char *__REDIRECT (__fgets_unlocked_chk_warn,
314 (char *__restrict __s, size_t __size, int __n,
315 FILE *__restrict __stream), __fgets_unlocked_chk)
316 __wur __warnattr ("fgets_unlocked called with bigger size than length "
317 "of destination buffer");
319 __fortify_function __wur __attr_access ((__write_only__, 1, 2)) char *
320 fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
322 if (__bos (__s) != (size_t) -1)
324 if (!__builtin_constant_p (__n) || __n <= 0)
325 return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream);
327 if ((size_t) __n > __bos (__s))
328 return __fgets_unlocked_chk_warn (__s, __bos (__s), __n, __stream);
330 return __fgets_unlocked_alias (__s, __n, __stream);
332 #endif
334 #ifdef __USE_MISC
335 # undef fread_unlocked
336 extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen,
337 size_t __size, size_t __n,
338 FILE *__restrict __stream) __wur;
339 extern size_t __REDIRECT (__fread_unlocked_alias,
340 (void *__restrict __ptr, size_t __size,
341 size_t __n, FILE *__restrict __stream),
342 fread_unlocked) __wur;
343 extern size_t __REDIRECT (__fread_unlocked_chk_warn,
344 (void *__restrict __ptr, size_t __ptrlen,
345 size_t __size, size_t __n,
346 FILE *__restrict __stream),
347 __fread_unlocked_chk)
348 __wur __warnattr ("fread_unlocked called with bigger size * nmemb than "
349 "length of destination buffer");
351 __fortify_function __wur size_t
352 fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
353 FILE *__restrict __stream)
355 if (__bos0 (__ptr) != (size_t) -1)
357 if (!__builtin_constant_p (__size)
358 || !__builtin_constant_p (__n)
359 || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)))
360 return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n,
361 __stream);
363 if (__size * __n > __bos0 (__ptr))
364 return __fread_unlocked_chk_warn (__ptr, __bos0 (__ptr), __size, __n,
365 __stream);
368 # ifdef __USE_EXTERN_INLINES
369 if (__builtin_constant_p (__size)
370 && __builtin_constant_p (__n)
371 && (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2))
372 && __size * __n <= 8)
374 size_t __cnt = __size * __n;
375 char *__cptr = (char *) __ptr;
376 if (__cnt == 0)
377 return 0;
379 for (; __cnt > 0; --__cnt)
381 int __c = getc_unlocked (__stream);
382 if (__c == EOF)
383 break;
384 *__cptr++ = __c;
386 return (__cptr - (char *) __ptr) / __size;
388 # endif
389 return __fread_unlocked_alias (__ptr, __size, __n, __stream);
391 #endif
393 #endif /* bits/stdio2.h. */