diff -urN stdio-common/format.c stdio-common/format.c --- stdio-common/format.c 1970-01-01 01:00:00.000000000 +0100 +++ stdio-common/format.c 2005-04-15 15:38:11.000000000 +0100 @@ -0,0 +1,53 @@ +#include "format.h" +#include +#include +#include +#include + +static int setup = 0; +static int format_log = 0; +static void *heap_start = 0x00; +static void *heap_end = 0x00; + +static void format_init(void) +{ + if (setup) + return; + else { + struct mallinfo malloc_info; + char *format_logging = NULL; + + setup = 1; + + format_logging = getenv("_FORMAT_CHECK"); + + if (!format_logging) + return; + + if (format_logging) + format_log = atoi(format_logging); + + malloc(0); + malloc_info = mallinfo(); + + heap_end = sbrk(0); + heap_start = heap_end - malloc_info.arena; + } +} + +void format_check(const char *function, const char *format, int length) +{ + format_init(); + + if (!format_log) + return; + if ((void *)format > heap_start && (void *)format < heap_end) { + if (format_log == 6) kill(getpid(), SIGSEGV); + __libc_message(0, (!(format_log & 2) || strchr(format, 0x25)) ? + "info: format string is non-literal: %s(\"%p\");\n": + "warn: non-literal format string contains no specifiers: %s(\"%p\");\n", + function, format); + } + if ((format_log & 2) && length && strstr(format, "%s")) + __libc_message(0, "warn: format string contains an (percent)s with no length modifier: %s(\"%p\");\n", function, format); +} diff -urN stdio-common/format.h stdio-common/format.h --- stdio-common/format.h 1970-01-01 01:00:00.000000000 +0100 +++ stdio-common/format.h 2005-04-15 15:38:11.000000000 +0100 @@ -0,0 +1,3 @@ +#include + +void format_check(const char *function, const char *format, int length); diff -urN stdio-common/fprintf.c stdio-common/fprintf.c --- stdio-common/fprintf.c 2004-03-19 00:21:39.000000000 +0000 +++ stdio-common/fprintf.c 2005-04-15 15:38:11.000000000 +0100 @@ -18,6 +18,7 @@ #include #include +#include "format.h" /* Write formatted output to STREAM from the format string FORMAT. */ @@ -28,6 +29,8 @@ va_list arg; int done; + format_check(__FUNCTION__, format, 0); + va_start (arg, format); done = vfprintf (stream, format, arg); va_end (arg); diff -urN stdio-common/Makefile stdio-common/Makefile --- stdio-common/Makefile 2004-08-10 19:01:29.000000000 +0100 +++ stdio-common/Makefile 2005-04-15 15:38:11.000000000 +0100 @@ -34,7 +34,7 @@ tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \ getline getw putw \ remove rename \ - flockfile ftrylockfile funlockfile + flockfile ftrylockfile funlockfile format install-others = $(inst_includedir)/bits/stdio_lim.h diff -urN stdio-common/printf.c stdio-common/printf.c --- stdio-common/printf.c 2004-03-19 00:21:39.000000000 +0000 +++ stdio-common/printf.c 2005-04-15 15:38:11.000000000 +0100 @@ -19,6 +19,7 @@ #include #include +#include "format.h" #undef printf @@ -30,6 +31,8 @@ va_list arg; int done; + format_check(__FUNCTION__, format, 0); + va_start (arg, format); done = vfprintf (stdout, format, arg); va_end (arg); diff -urN stdio-common/snprintf.c stdio-common/snprintf.c --- stdio-common/snprintf.c 2004-03-19 00:21:39.000000000 +0000 +++ stdio-common/snprintf.c 2005-04-15 15:38:11.000000000 +0100 @@ -31,6 +31,8 @@ va_list arg; int done; + format_check(__FUNCTION__, format, 0); + va_start (arg, format); done = __vsnprintf (s, maxlen, format, arg); va_end (arg); diff -urN stdio-common/sprintf.c stdio-common/sprintf.c --- stdio-common/sprintf.c 2004-03-19 00:21:39.000000000 +0000 +++ stdio-common/sprintf.c 2005-04-15 15:38:11.000000000 +0100 @@ -30,6 +30,8 @@ va_list arg; int done; + format_check(__FUNCTION__, format, 0); + va_start (arg, format); done = vsprintf (s, format, arg); va_end (arg); diff -urN stdio-common/vfprintf.c stdio-common/vfprintf.c --- stdio-common/vfprintf.c 2004-11-18 23:34:21.000000000 +0000 +++ stdio-common/vfprintf.c 2005-04-15 15:38:11.000000000 +0100 @@ -30,6 +30,7 @@ #include "_itoa.h" #include #include +#include "format.h" /* This code is shared between the standard stdio implementation found in GNU C library and the libio implementation originally found in @@ -1228,6 +1229,8 @@ ORIENT; #endif + format_check(__FUNCTION__, format, 0); + /* Sanity check of arguments. */ ARGCHECK (s, format); diff -urN stdio-common/vfscanf.c stdio-common/vfscanf.c --- stdio-common/vfscanf.c 2004-10-11 23:22:25.000000000 +0100 +++ stdio-common/vfscanf.c 2005-04-15 15:38:11.000000000 +0100 @@ -29,6 +29,7 @@ #include #include #include +#include "format.h" #ifdef __GNUC__ # define HAVE_LONGLONG @@ -281,6 +282,8 @@ ORIENT; #endif + format_check(__FUNCTION__, format, 1); + ARGCHECK (s, format); { diff -urN stdio-common/vprintf.c stdio-common/vprintf.c --- stdio-common/vprintf.c 2001-07-06 05:55:41.000000000 +0100 +++ stdio-common/vprintf.c 2005-04-15 15:38:11.000000000 +0100 @@ -29,5 +29,7 @@ const char *format; __gnuc_va_list arg; { + format_check(__FUNCTION__, format, 0); + return vfprintf (stdout, format, arg); }