changeset 5217:dfed7854bcf3

Improve handling of the case length > INT_MAX.
author Bruno Haible <bruno@clisp.org>
date Wed, 08 Sep 2004 12:11:19 +0000
parents e380573abea1
children f96c64693f86
files lib/ChangeLog lib/vasnprintf.c lib/vasprintf.c
diffstat 3 files changed, 22 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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 @@
       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);
--- 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 @@
   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;
 }