summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2004-09-08 12:11:19 +0000
committerBruno Haible <bruno@clisp.org>2004-09-08 12:11:19 +0000
commit372b0b04326df8b7220d89c0ebe93b58befacf2b (patch)
treefe764a0a627713797471089d5759eac72f58261f
parentfb6d56cd715b44290122f52bded998bdc46c679d (diff)
downloadgnulib-372b0b04326df8b7220d89c0ebe93b58befacf2b.tar.gz
Improve handling of the case length > INT_MAX.
-rw-r--r--lib/ChangeLog6
-rw-r--r--lib/vasnprintf.c13
-rw-r--r--lib/vasprintf.c14
3 files changed, 22 insertions, 11 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog
index b51f505704..e77d548017 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,9 @@
+2004-09-08 Bruno Haible <bruno@clisp.org>
+
+ * 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 <eggert@cs.ucla.edu>
Import from coreutils.
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 0fa24708fe..ff80857305 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -40,7 +40,7 @@
#include <stdlib.h> /* abort(), malloc(), realloc(), free() */
#include <string.h> /* memcpy(), strlen() */
#include <errno.h> /* errno */
-#include <limits.h> /* CHAR_BIT */
+#include <limits.h> /* CHAR_BIT, INT_MAX */
#include <float.h> /* 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 bda9aa1b0f..ba94c64ba8 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 <limits.h>
#include <stdlib.h>
#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;
}