* libio/bits/stdio2.h (__fread_chk, __fread_unlocked_chk): New
prototypes. (__fread_alias, __fread_unlocked_alias): New aliases. (fread): New extern inline. (fread_unlocked): Likewise. Undef macro before definition of the inline function. * debug/Makefile (routines): Add fread_chk and fread_u_chk. (CFLAGS-fread_chk.c, CFLAGS-fread_u_chk.c): Add. * debug/Versions (libc): Export __fread_chk@@GLIBC_2.7 and __fread_unlocked_chk@@GLIBC_2.7. * debug/fread_chk.c: New file. * debug/fread_u_chk.c: New file. * debug/tst-chk1.c (do_test): Add fread and fread_unlocked tests.
This commit is contained in:
parent
cba5c7c073
commit
3586b2b60b
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
||||
2007-08-28 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* libio/bits/stdio2.h (__fread_chk, __fread_unlocked_chk): New
|
||||
prototypes.
|
||||
(__fread_alias, __fread_unlocked_alias): New aliases.
|
||||
(fread): New extern inline.
|
||||
(fread_unlocked): Likewise. Undef macro before definition of
|
||||
the inline function.
|
||||
* debug/Makefile (routines): Add fread_chk and fread_u_chk.
|
||||
(CFLAGS-fread_chk.c, CFLAGS-fread_u_chk.c): Add.
|
||||
* debug/Versions (libc): Export __fread_chk@@GLIBC_2.7
|
||||
and __fread_unlocked_chk@@GLIBC_2.7.
|
||||
* debug/fread_chk.c: New file.
|
||||
* debug/fread_u_chk.c: New file.
|
||||
* debug/tst-chk1.c (do_test): Add fread and fread_unlocked tests.
|
||||
|
||||
2007-08-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscalls.list
|
||||
|
@ -32,7 +32,7 @@ routines = backtrace backtracesyms backtracesymsfd noophooks \
|
||||
gets_chk chk_fail readonly-area fgets_chk fgets_u_chk \
|
||||
read_chk pread_chk pread64_chk recv_chk recvfrom_chk \
|
||||
readlink_chk readlinkat_chk getwd_chk getcwd_chk \
|
||||
realpath_chk ptsname_r_chk \
|
||||
realpath_chk ptsname_r_chk fread_chk fread_u_chk \
|
||||
wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
|
||||
wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
|
||||
wcpncpy_chk \
|
||||
@ -58,6 +58,8 @@ CFLAGS-vfprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-gets_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-fgets_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-fgets_u_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-fread_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-fread_u_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
CFLAGS-swprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-vswprintf_chk.c = -D_IO_MTSAFE_IO
|
||||
CFLAGS-wprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions)
|
||||
|
@ -39,4 +39,7 @@ libc {
|
||||
GLIBC_2.5 {
|
||||
__readlinkat_chk;
|
||||
}
|
||||
GLIBC_2.7 {
|
||||
__fread_chk; __fread_unlocked_chk;
|
||||
}
|
||||
}
|
||||
|
54
debug/fread_u_chk.c
Normal file
54
debug/fread_u_chk.c
Normal file
@ -0,0 +1,54 @@
|
||||
/* Copyright (C) 1993, 1995, 1997, 1998, 1999, 2002, 2003, 2007
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
As a special exception, if you link the code in this file with
|
||||
files compiled with a GNU compiler to produce an executable,
|
||||
that does not cause the resulting executable to be covered by
|
||||
the GNU Lesser General Public License. This exception does not
|
||||
however invalidate any other reasons why the executable file
|
||||
might be covered by the GNU Lesser General Public License.
|
||||
This exception applies to code released by its copyright holders
|
||||
in files containing the exception. */
|
||||
|
||||
#include "libioP.h"
|
||||
#include <stdio.h>
|
||||
|
||||
size_t
|
||||
__fread_unlocked_chk (void *__restrict ptr, size_t ptrlen,
|
||||
size_t size, size_t n, FILE *__restrict stream)
|
||||
{
|
||||
size_t bytes_requested = size * n;
|
||||
if (__builtin_expect ((n | size)
|
||||
>= (((size_t) 1) << (8 * sizeof (size_t) / 2)), 0))
|
||||
{
|
||||
if (size != 0 && bytes_requested / size != n)
|
||||
__chk_fail ();
|
||||
}
|
||||
|
||||
if (__builtin_expect (bytes_requested > ptrlen, 0))
|
||||
__chk_fail ();
|
||||
|
||||
CHECK_FILE (stream, 0);
|
||||
if (bytes_requested == 0)
|
||||
return 0;
|
||||
|
||||
size_t bytes_read
|
||||
= INTUSE(_IO_sgetn) (stream, (char *) ptr, bytes_requested);
|
||||
return bytes_requested == bytes_read ? n : bytes_read / size;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
|
||||
|
||||
@ -746,6 +746,75 @@ do_test (void)
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
if (fread (buf, 1, sizeof (buf), stdin) != sizeof (buf)
|
||||
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||
FAIL ();
|
||||
if (fread (buf, sizeof (buf), 1, stdin) != 1
|
||||
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||
FAIL ();
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
if (fread (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
|
||||
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||
FAIL ();
|
||||
if (fread (buf, sizeof (buf), l0 + 1, stdin) != 1
|
||||
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
if (fread (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
if (fread (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
if (fread_unlocked (buf, 1, sizeof (buf), stdin) != sizeof (buf)
|
||||
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||
FAIL ();
|
||||
if (fread_unlocked (buf, sizeof (buf), 1, stdin) != 1
|
||||
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||
FAIL ();
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
if (fread_unlocked (buf, 1, 4, stdin) != 4
|
||||
|| memcmp (buf, "abcdFGHI\na", 10))
|
||||
FAIL ();
|
||||
if (fread_unlocked (buf, 4, 1, stdin) != 1
|
||||
|| memcmp (buf, "efghFGHI\na", 10))
|
||||
FAIL ();
|
||||
|
||||
rewind (stdin);
|
||||
|
||||
if (fread_unlocked (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
|
||||
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||
FAIL ();
|
||||
if (fread_unlocked (buf, sizeof (buf), l0 + 1, stdin) != 1
|
||||
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||
FAIL ();
|
||||
|
||||
#if __USE_FORTIFY_LEVEL >= 1
|
||||
CHK_FAIL_START
|
||||
if (fread_unlocked (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
if (fread_unlocked (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
|
||||
FAIL ();
|
||||
CHK_FAIL_END
|
||||
#endif
|
||||
|
||||
lseek (fileno (stdin), 0, SEEK_SET);
|
||||
|
||||
if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
|
||||
|
@ -98,6 +98,27 @@ fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
|
||||
return __fgets_alias (__s, __n, __stream);
|
||||
}
|
||||
|
||||
extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen,
|
||||
size_t __size, size_t __n,
|
||||
FILE *__restrict __stream) __wur;
|
||||
extern size_t __REDIRECT (__fread_alias,
|
||||
(void *__restrict __ptr, size_t __size,
|
||||
size_t __n, FILE *__restrict __stream),
|
||||
fread) __wur;
|
||||
|
||||
__extern_always_inline __wur size_t
|
||||
fread (void *__restrict __ptr, size_t __size, size_t __n,
|
||||
FILE *__restrict __stream)
|
||||
{
|
||||
if (__bos0 (__ptr) != (size_t) -1
|
||||
&& (!__builtin_constant_p (__size)
|
||||
|| !__builtin_constant_p (__n)
|
||||
|| (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))
|
||||
|| __size * __n > __bos0 (__ptr)))
|
||||
return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
|
||||
return __fread_alias (__ptr, __size, __n, __stream);
|
||||
}
|
||||
|
||||
#ifdef __USE_GNU
|
||||
extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size,
|
||||
int __n, FILE *__restrict __stream) __wur;
|
||||
@ -114,3 +135,49 @@ fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
|
||||
return __fgets_unlocked_alias (__s, __n, __stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __USE_MISC
|
||||
# undef fread_unlocked
|
||||
extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen,
|
||||
size_t __size, size_t __n,
|
||||
FILE *__restrict __stream) __wur;
|
||||
extern size_t __REDIRECT (__fread_unlocked_alias,
|
||||
(void *__restrict __ptr, size_t __size,
|
||||
size_t __n, FILE *__restrict __stream),
|
||||
fread_unlocked) __wur;
|
||||
|
||||
__extern_always_inline __wur size_t
|
||||
fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
|
||||
FILE *__restrict __stream)
|
||||
{
|
||||
if (__bos0 (__ptr) != (size_t) -1
|
||||
&& (!__builtin_constant_p (__size)
|
||||
|| !__builtin_constant_p (__n)
|
||||
|| (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))
|
||||
|| __size * __n > __bos0 (__ptr)))
|
||||
return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
|
||||
|
||||
# ifdef __USE_EXTERN_INLINES
|
||||
if (__builtin_constant_p (__size)
|
||||
&& __builtin_constant_p (__n)
|
||||
&& (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2))
|
||||
&& __size * __n <= 8)
|
||||
{
|
||||
size_t __cnt = __size * __n;
|
||||
char *__cptr = (char *) __ptr;
|
||||
if (__cnt == 0)
|
||||
return 0;
|
||||
|
||||
for (; __cnt > 0; --__cnt)
|
||||
{
|
||||
int __c = _IO_getc_unlocked (__stream);
|
||||
if (__c == EOF)
|
||||
break;
|
||||
*__cptr++ = __c;
|
||||
}
|
||||
return (__cptr - (char *) __ptr) / __size;
|
||||
}
|
||||
# endif
|
||||
return __fread_unlocked_alias (__ptr, __size, __n, __stream);
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user