FORTIFY_SOURCE: add fgets support.

Change-Id: I8c3410a90c71a3336c4ac8581618fa9330edf5e3
This commit is contained in:
Nick Kralevich
2012-07-03 11:45:31 -07:00
parent 2ddf77b377
commit 965dbc6405
3 changed files with 100 additions and 0 deletions

View File

@@ -527,6 +527,45 @@ int sprintf(char *dest, const char *format, ...)
# endif /* !defined(__clang__) */
extern char *__fgets_real(char *, int, FILE *)
__asm__(__USER_LABEL_PREFIX__ "fgets");
extern void __fgets_too_big_error()
__attribute__((__error__("fgets called with size bigger than buffer")));
extern void __fgets_too_small_error()
__attribute__((__error__("fgets called with size less than zero")));
extern char *__fgets_chk(char *, int, FILE *, size_t);
__BIONIC_FORTIFY_INLINE
char *fgets(char *dest, int size, FILE *stream)
{
size_t bos = __builtin_object_size(dest, 0);
// Compiler can prove, at compile time, that the passed in size
// is always negative. Force a compiler error.
if (__builtin_constant_p(size) && (size < 0)) {
__fgets_too_small_error();
}
// Compiler doesn't know destination size. Don't call __fgets_chk
if (bos == (size_t) -1) {
return __fgets_real(dest, size, stream);
}
// Compiler can prove, at compile time, that the passed in size
// is always <= the actual object size. Don't call __fgets_chk
if (__builtin_constant_p(size) && (size <= bos)) {
return __fgets_real(dest, size, stream);
}
// Compiler can prove, at compile time, that the passed in size
// is always > the actual object size. Force a compiler error.
if (__builtin_constant_p(size) && (size > bos)) {
__fgets_too_big_error();
}
return __fgets_chk(dest, size, stream, bos);
}
#endif /* defined(__BIONIC_FORTIFY_INLINE) */
#endif /* _STDIO_H_ */