From 0ceb73fb1052345c4a0e20f27c70b078b1b837a6 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 2 Mar 2019 06:52:00 +0000 Subject: [PATCH] dupvprintf: fix signedness of return from vsnprintf. It's defined in the C standard to return an int, not a size_t, and we should honour that since the subsequent code checks it for <0. A knock-on effect is that I reorganise the addends in one of the sgrowarrays, to be extra careful about overflow when adding something to that int. --- utils.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/utils.c b/utils.c index f4ce54a9..f87596eb 100644 --- a/utils.c +++ b/utils.c @@ -340,15 +340,13 @@ int string_length_for_printf(size_t s) static char *dupvprintf_inner(char *buf, size_t oldlen, size_t *sizeptr, const char *fmt, va_list ap) { - size_t len, size; - - size = *sizeptr; + size_t size = *sizeptr; sgrowarrayn_nm(buf, size, oldlen, 512); while (1) { va_list aq; va_copy(aq, ap); - len = vsnprintf(buf + oldlen, size - oldlen, fmt, aq); + int len = vsnprintf(buf + oldlen, size - oldlen, fmt, aq); va_end(aq); if (len >= 0 && len < size) { @@ -359,7 +357,7 @@ static char *dupvprintf_inner(char *buf, size_t oldlen, size_t *sizeptr, } else if (len > 0) { /* This is the C99 error condition: the returned length is * the required buffer size not counting the NUL. */ - sgrowarrayn_nm(buf, size, oldlen, len + 1); + sgrowarrayn_nm(buf, size, oldlen + 1, len); } else { /* This is the pre-C99 glibc error condition: <0 means the * buffer wasn't big enough, so we enlarge it a bit and hope. */