summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/stdio/snprintf.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c
index 4b6c9202a2d..ab44d6128d9 100644
--- a/lib/libc/stdio/snprintf.c
+++ b/lib/libc/stdio/snprintf.c
@@ -31,7 +31,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: snprintf.c,v 1.8 2003/06/02 20:18:37 millert Exp $";
+static char rcsid[] = "$OpenBSD: snprintf.c,v 1.9 2004/04/10 19:34:44 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <limits.h>
@@ -41,21 +41,26 @@ static char rcsid[] = "$OpenBSD: snprintf.c,v 1.8 2003/06/02 20:18:37 millert Ex
int
snprintf(char *str, size_t n, char const *fmt, ...)
{
- int ret;
va_list ap;
+ int ret;
+ char dummy;
FILE f;
/* While snprintf(3) specifies size_t stdio uses an int internally */
if (n > INT_MAX)
n = INT_MAX;
+ /* Stdio internals do not deal correctly with zero length buffer */
+ if (n == 0) {
+ str = &dummy;
+ n = 1;
+ }
va_start(ap, fmt);
f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = n ? n - 1 : 0;
+ f._bf._size = f._w = n - 1;
ret = vfprintf(&f, fmt, ap);
- if (n)
- *f._p = '\0';
+ *f._p = '\0';
va_end(ap);
return (ret);
}