Hi, Aaron Stone wrote: > When glibc gets a null pointer in one of the printf-family of functions > for a %s argument, it prints "(null)" and doesn't crash. All of the > *BSD's libc's also print "(null)". > > Gnulib, when using its own vasnprintf implementation, does crash. The > principal offender is Solaris, for which a) this would normally crash > their in libc
Then the argument about the glibc behaviour and the *BSD libc behaviour is moot: if there's a single platform where it crashes, and if the standard says that NULL are invalid arguments, gnulib's implementation can crash as well. > This patch, submitted to Glib last May, appears to correct this: > http://mail.gnome.org/archives/gtk-devel-list/2005-May/msg00031.html But this mail contains also a different justification: use of printf for debug output. For this case, it does not make sense to let the user change, recompile, relink and rerun his program, when all he wants is debugging output. I'm applying the appended patch. Bruno 2006-05-24 Bruno Haible <[EMAIL PROTECTED]> * printf-args.c (printf_fetchargs): Turn NULL pointers for TYPE_STRING and TYPE_WIDE_STRING into a non-NULL replacement. Reported by Thorsten Maerz <[EMAIL PROTECTED]> via Aaron Stone <[EMAIL PROTECTED]>. diff -c -3 -r1.4 printf-args.c *** printf-args.c 14 May 2005 06:03:58 -0000 1.4 --- printf-args.c 24 May 2006 11:42:04 -0000 *************** *** 1,5 **** /* Decomposed printf argument list. ! Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by --- 1,5 ---- /* Decomposed printf argument list. ! Copyright (C) 1999, 2002-2003, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by *************** *** 84,93 **** --- 84,112 ---- #endif case TYPE_STRING: ap->a.a_string = va_arg (args, const char *); + /* A null pointer is an invalid argument for "%s", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_string == NULL) + ap->a.a_string = "(NULL)"; break; #ifdef HAVE_WCHAR_T case TYPE_WIDE_STRING: ap->a.a_wide_string = va_arg (args, const wchar_t *); + /* A null pointer is an invalid argument for "%ls", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_wide_string == NULL) + { + static const wchar_t wide_null_string[] = + { + (wchar_t)'(', + (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L', + (wchar_t)')', + (wchar_t)0 + }; + ap->a.a_wide_string = wide_null_string; + } break; #endif case TYPE_POINTER: