# HG changeset patch # User Eric Blake # Date 1333049441 21600 # Node ID 7ebb2c82d76fcf8b572ace5a9037d828757a2d6d # Parent bc20efc34ebad313c05fb1bb55ad717d07eda709 stdio: don't assume gets any more Gnulib intentionally does not have a gets module, and now that C11 and glibc have dropped it, we should be more proactive about warning any user on a platform that still has a declaration of this dangerous interface. * m4/stdio_h.m4 (gl_STDIO_H, gl_STDIO_H_DEFAULTS): Drop gets support. * modules/stdio (Makefile.am): Likewise. * lib/stdio-read.c (gets): Likewise. * tests/test-stdio-c++.cc: Likewise. * m4/warn-on-use.m4 (gl_WARN_ON_USE_PREPARE): Fix comment. * lib/stdio.in.h (gets): Make warning occur in more places. * doc/posix-functions/gets.texi (gets): Update documentation. Reported by Christer Solskogen. Signed-off-by: Eric Blake diff -r bc20efc34eba -r 7ebb2c82d76f ChangeLog --- a/ChangeLog Thu Jan 03 14:26:52 2013 -0500 +++ b/ChangeLog Thu Mar 29 13:30:41 2012 -0600 @@ -1,3 +1,16 @@ +2012-03-29 Eric Blake + + stdio: don't assume gets any more + * m4/stdio_h.m4 (gl_STDIO_H, gl_STDIO_H_DEFAULTS): Drop gets + support. + * modules/stdio (Makefile.am): Likewise. + * lib/stdio-read.c (gets): Likewise. + * tests/test-stdio-c++.cc: Likewise. + * m4/warn-on-use.m4 (gl_WARN_ON_USE_PREPARE): Fix comment. + * lib/stdio.in.h (gets): Make warning occur in more places. + * doc/posix-functions/gets.texi (gets): Update documentation. + Reported by Christer Solskogen. + 2012-01-10 Jim Meyering maint.mk: fix description in comment diff -r bc20efc34eba -r 7ebb2c82d76f doc/posix-functions/gets.texi --- a/doc/posix-functions/gets.texi Thu Jan 03 14:26:52 2013 -0500 +++ b/doc/posix-functions/gets.texi Thu Mar 29 13:30:41 2012 -0600 @@ -4,15 +4,10 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/gets.html} -Gnulib module: stdio, nonblocking +Gnulib module: --- -Portability problems fixed by Gnulib module @code{stdio}, together with module @code{nonblocking}: +Portability problems fixed by Gnulib: @itemize -@item -When reading from a non-blocking pipe whose buffer is empty, this function -fails with @code{errno} being set to @code{EINVAL} instead of @code{EAGAIN} on -some platforms: -mingw, MSVC 9. @end itemize Portability problems not fixed by Gnulib: @@ -20,6 +15,11 @@ @item This function should never be used, because it can overflow any given buffer. @item +When reading from a non-blocking pipe whose buffer is empty, this function +fails with @code{errno} being set to @code{EINVAL} instead of @code{EAGAIN} on +some platforms: +mingw, MSVC 9. +@item On Windows platforms (excluding Cygwin), this function does not set @code{errno} upon failure. @end itemize diff -r bc20efc34eba -r 7ebb2c82d76f lib/stdio-read.c --- a/lib/stdio-read.c Thu Jan 03 14:26:52 2013 -0500 +++ b/lib/stdio-read.c Thu Mar 29 13:30:41 2012 -0600 @@ -131,13 +131,7 @@ CALL_WITH_ERRNO_FIX (char *, fgets (s, n, stream), ret == NULL) } -char * -gets (char *s) -#undef gets -{ - FILE *stream = stdin; - CALL_WITH_ERRNO_FIX (char *, gets (s), ret == NULL) -} +/* We intentionally don't bother to fix gets. */ size_t fread (void *ptr, size_t s, size_t n, FILE *stream) diff -r bc20efc34eba -r 7ebb2c82d76f lib/stdio.in.h --- a/lib/stdio.in.h Thu Jan 03 14:26:52 2013 -0500 +++ b/lib/stdio.in.h Thu Mar 29 13:30:41 2012 -0600 @@ -699,22 +699,11 @@ # endif #endif -#if @GNULIB_GETS@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef gets -# define gets rpl_gets -# endif -_GL_FUNCDECL_RPL (gets, char *, (char *s) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (gets, char *, (char *s)); -# else -_GL_CXXALIAS_SYS (gets, char *, (char *s)); -# undef gets -# endif -_GL_CXXALIASWARN (gets); /* It is very rare that the developer ever has full control of stdin, - so any use of gets warrants an unconditional warning. Assume it is - always declared, since it is required by C89. */ + so any use of gets warrants an unconditional warning; besides, C11 + removed it. */ +#undef gets +#if HAVE_RAW_DECL_GETS _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); #endif @@ -1054,9 +1043,9 @@ # endif #endif -/* Some people would argue that sprintf should be handled like gets - (for example, OpenBSD issues a link warning for both functions), - since both can cause security holes due to buffer overruns. +/* Some people would argue that all sprintf uses should be warned about + (for example, OpenBSD issues a link warning for it), + since it can cause security holes due to buffer overruns. However, we believe that sprintf can be used safely, and is more efficient than snprintf in those safe cases; and as proof of our belief, we use sprintf in several gnulib modules. So this header diff -r bc20efc34eba -r 7ebb2c82d76f m4/stdio_h.m4 --- a/m4/stdio_h.m4 Thu Jan 03 14:26:52 2013 -0500 +++ b/m4/stdio_h.m4 Thu Mar 29 13:30:41 2012 -0600 @@ -1,4 +1,4 @@ -# stdio_h.m4 serial 40 +# stdio_h.m4 serial 41 dnl Copyright (C) 2007-2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -18,7 +18,6 @@ GNULIB_GETC=1 GNULIB_GETCHAR=1 GNULIB_FGETS=1 - GNULIB_GETS=1 GNULIB_FREAD=1 dnl This ifdef is necessary to avoid an error "missing file lib/stdio-read.c" dnl "expected source file, required through AC_LIBSOURCES, not found". It is @@ -72,10 +71,10 @@ dnl Check for declarations of anything we want to poison if the dnl corresponding gnulib module is not in use, and which is not - dnl guaranteed by C89. + dnl guaranteed by both C89 and C11. gl_WARN_ON_USE_PREPARE([[#include - ]], [dprintf fpurge fseeko ftello getdelim getline pclose popen renameat - snprintf tmpfile vdprintf vsnprintf]) + ]], [dprintf fpurge fseeko ftello getdelim getline gets pclose popen + renameat snprintf tmpfile vdprintf vsnprintf]) ]) AC_DEFUN([gl_STDIO_MODULE_INDICATOR], @@ -113,7 +112,6 @@ GNULIB_GETCHAR=0; AC_SUBST([GNULIB_GETCHAR]) GNULIB_GETDELIM=0; AC_SUBST([GNULIB_GETDELIM]) GNULIB_GETLINE=0; AC_SUBST([GNULIB_GETLINE]) - GNULIB_GETS=0; AC_SUBST([GNULIB_GETS]) GNULIB_OBSTACK_PRINTF=0; AC_SUBST([GNULIB_OBSTACK_PRINTF]) GNULIB_OBSTACK_PRINTF_POSIX=0; AC_SUBST([GNULIB_OBSTACK_PRINTF_POSIX]) GNULIB_PCLOSE=0; AC_SUBST([GNULIB_PCLOSE]) diff -r bc20efc34eba -r 7ebb2c82d76f m4/warn-on-use.m4 --- a/m4/warn-on-use.m4 Thu Jan 03 14:26:52 2013 -0500 +++ b/m4/warn-on-use.m4 Thu Mar 29 13:30:41 2012 -0600 @@ -1,4 +1,4 @@ -# warn-on-use.m4 serial 4 +# warn-on-use.m4 serial 5 dnl Copyright (C) 2010-2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -18,8 +18,8 @@ # some systems declare functions in the wrong header, then INCLUDES # should do likewise. # -# If you assume C89, then it is generally safe to assume declarations -# for functions declared in that standard (such as gets) without +# It is generally safe to assume declarations for functions declared +# in the intersection of C89 and C11 (such as printf) without # needing gl_WARN_ON_USE_PREPARE. AC_DEFUN([gl_WARN_ON_USE_PREPARE], [ diff -r bc20efc34eba -r 7ebb2c82d76f modules/stdio --- a/modules/stdio Thu Jan 03 14:26:52 2013 -0500 +++ b/modules/stdio Thu Mar 29 13:30:41 2012 -0600 @@ -53,7 +53,6 @@ -e 's/@''GNULIB_GETCHAR''@/$(GNULIB_GETCHAR)/g' \ -e 's/@''GNULIB_GETDELIM''@/$(GNULIB_GETDELIM)/g' \ -e 's/@''GNULIB_GETLINE''@/$(GNULIB_GETLINE)/g' \ - -e 's/@''GNULIB_GETS''@/$(GNULIB_GETS)/g' \ -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GNULIB_OBSTACK_PRINTF)/g' \ -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GNULIB_OBSTACK_PRINTF_POSIX)/g' \ -e 's/@''GNULIB_PCLOSE''@/$(GNULIB_PCLOSE)/g' \ diff -r bc20efc34eba -r 7ebb2c82d76f tests/test-stdio-c++.cc --- a/tests/test-stdio-c++.cc Thu Jan 03 14:26:52 2013 -0500 +++ b/tests/test-stdio-c++.cc Thu Mar 29 13:30:41 2012 -0600 @@ -122,9 +122,7 @@ (char **, size_t *, FILE *)); #endif -#if GNULIB_TEST_GETS -SIGNATURE_CHECK (GNULIB_NAMESPACE::gets, char *, (char *)); -#endif +/* Don't bother testing gets; it should never be used. */ #if GNULIB_TEST_OBSTACK_PRINTF || GNULIB_TEST_OBSTACK_PRINTF_POSIX SIGNATURE_CHECK (GNULIB_NAMESPACE::obstack_printf, int,