From 372b0b04326df8b7220d89c0ebe93b58befacf2b Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 8 Sep 2004 12:11:19 +0000 Subject: [PATCH] Improve handling of the case length > INT_MAX. --- lib/ChangeLog | 6 ++++++ lib/vasnprintf.c | 13 ++++++++++++- lib/vasprintf.c | 14 ++++---------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index b51f50570..e77d54801 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,9 @@ +2004-09-08 Bruno Haible + + * vasnprintf.c (VASNPRINTF): Signal EOVERFLOW if the resulting length + is > INT_MAX. + * vasprintf.c (vasprintf): Don't test for length > INT_MAX any more. + 2004-08-19 Paul Eggert Import from coreutils. diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c index 0fa24708f..ff8085730 100644 --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -40,7 +40,7 @@ #include /* abort(), malloc(), realloc(), free() */ #include /* memcpy(), strlen() */ #include /* errno */ -#include /* CHAR_BIT */ +#include /* CHAR_BIT, INT_MAX */ #include /* DBL_MAX_EXP, LDBL_MAX_EXP */ #if WIDE_CHAR_VERSION # include "wprintf-parse.h" @@ -862,8 +862,19 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar free (buf_malloced); CLEANUP (); *lengthp = length; + if (length > INT_MAX) + goto length_overflow; return result; + length_overflow: + /* We could produce such a big string, but its length doesn't fit into + an 'int'. POSIX says that snprintf() fails with errno = EOVERFLOW in + this case. */ + if (result != resultbuf) + free (result); + errno = EOVERFLOW; + return NULL; + out_of_memory: if (!(result == resultbuf || result == NULL)) free (result); diff --git a/lib/vasprintf.c b/lib/vasprintf.c index bda9aa1b0..ba94c64ba 100644 --- a/lib/vasprintf.c +++ b/lib/vasprintf.c @@ -1,5 +1,5 @@ /* Formatted output to strings. - Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2002-2004 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 @@ -22,7 +22,6 @@ /* Specification. */ #include "vasprintf.h" -#include #include #include "vasnprintf.h" @@ -34,15 +33,10 @@ vasprintf (char **resultp, const char *format, va_list args) char *result = vasnprintf (NULL, &length, format, args); if (result == NULL) return -1; - if (length > INT_MAX) - { - /* We could produce such a big string, but can't return its length - as an 'int'. */ - free (result); - return -1; - } *resultp = result; - /* Return the number of resulting bytes, excluding the trailing NUL. */ + /* Return the number of resulting bytes, excluding the trailing NUL. + If it wouldn't fit in an 'int', vasnprintf() would have returned NULL + and set errno to EOVERFLOW. */ return length; } -- 2.11.0