[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 4.0 core dump from printf -v foo %s b
From: |
Greg Wooledge |
Subject: |
Re: 4.0 core dump from printf -v foo %s b |
Date: |
Thu, 12 Nov 2009 09:05:34 -0500 |
User-agent: |
Mutt/1.4.2.3i |
On Wed, Nov 11, 2009 at 09:41:29PM -0500, Chet Ramey wrote:
> If your version of vsnprintf doesn't behave like that, I claim it's a
> bug. The Posix and C standards explicitly allow the buffer to be NULL
> if the size argument is 0, and guarantee that no data will be written
> in this case.
Thanks for the explanation. HP-UX 10.20 has no manual page for
vsnprintf (or for snprintf), and vsnprintf does not appear in any
header file in /usr/include, at all. But vsnprintf _is_ defined in
libc:
imadev:~$ nm /usr/lib/libc.a | grep vsnprintf
U _vsnprintf
vsnprintf.o:
00000000 W vsnprintf
00000000 T _vsnprintf
imadev:~$ nm /usr/lib/libc.sl | grep vsnprintf
00121db8 T vsnprintf
00121dd0 T vsnprintf
00121dd0 T _vsnprintf
U _vsnprintf
00121da0 T _vsnprintf
I wrote this test program:
#include <stdio.h>
#include <stdarg.h>
void foo(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vsnprintf(NULL, 0, fmt, args);
va_end(args);
}
main() {
foo("%s", "");
return 0;
}
HP-UX 10.20 dumps core:
imadev:~$ uname -a
HP-UX imadev B.10.20 A 9000/785 2008897791 two-user license
imadev:~$ /net/appl/gcc-3.3/bin/gcc -o foo foo.c
imadev:~$ ./foo
Segmentation fault (core dumped)
HP-UX 11.11 dumps core:
bash-3.2# uname -a
HP-UX dev3 B.11.11 U 9000/778 2005106987 unlimited-user license
bash-3.2# gcc -o foo foo.c
bash-3.2# ./foo
Segmentation fault (core dumped)
OpenBSD 4.6 and Debian GNU/Linux 3.1 (and unstable) seem to like it,
though. At least they didn't dump core.
HP-UX 11.11 has a man page for vsnprintf (same page as vsprintf), but
all it says is:
vprintf(), vfprintf(), vsprintf(), and vsnprintf() are the same as
printf(), fprintf(), sprintf(), and snprintf() respectively, except
that instead of being called with a variable number of arguments, they
are called with an argument list as defined by <stdarg.h>.
It doesn't mention a null pointer. The OpenBSD man page does explicitly
say the null pointer is allowed if size is zero. The GNU/Linux man page
says that SUSv2 and C99 disagree, but that the implementation follows
C99 (allowing the null pointer when size is 0).
Fun stuff. Maybe it needs an autoconf test for broken (or pre-C99)
vsnprintf, with a wrapper function to test for size==0 and just return 0,
to be used when autoconf detects the broken vsnprintf. You may use my
test program (above) if you like, though I'm not an autoconf guru, so
maybe a really-portable test program would need something more (like a
setrlimit(RLIMIT_CORE, ...) call to stop actual core dumps?).