]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Be careful about using alloca.
authorBruno Haible <bruno@clisp.org>
Tue, 18 Nov 2003 15:25:27 +0000 (15:25 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:11:18 +0000 (12:11 +0200)
gettext-runtime/intl/ChangeLog
gettext-runtime/intl/vasnprintf.c
gettext-runtime/libasprintf/ChangeLog
gettext-runtime/libasprintf/vasnprintf.c

index 484836c3db9287b545eed0f25fb7ebbca2479f27..1d13498bb0da068f50b4e5b2233465aa9a9ab641 100644 (file)
@@ -1,3 +1,10 @@
+2003-11-17  Bruno Haible  <bruno@clisp.org>
+
+       * vasnprintf.c (alloca): Remove fallback definition.
+       (freea): Remove definition.
+       (VASNPRINTF): Use alloca only for small sizes, say <= 4000 bytes.
+       Reported by Paul Eggert.
+
 2003-11-16  Paul Eggert  <eggert@twinsun.com>
             Bruno Haible  <bruno@clisp.org>
 
index 1415a6f5a8fcb90592c480f45db2970bf7bb6107..05a08bcfb3a23b0e27196054df834a7356b89cb8 100644 (file)
 /* Checked size_t computations.  */
 #include "xsize.h"
 
-/* For those losing systems which don't have 'alloca' we have to add
-   some additional code emulating it.  */
-#ifdef HAVE_ALLOCA
-# define freea(p) /* nothing */
-#else
-# define alloca(n) malloc (n)
-# define freea(p) free (p)
-#endif
-
 #ifdef HAVE_WCHAR_T
 # ifdef HAVE_WCSLEN
 #  define local_wcslen wcslen
@@ -140,10 +131,9 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
     }
 
   {
-    size_t buf_neededlength =
-      xsum4 (7, d.max_width_length, d.max_precision_length, 6);
-    CHAR_T *buf =
-      (CHAR_T *) alloca (xtimes (buf_neededlength, sizeof (CHAR_T)));
+    size_t buf_neededlength;
+    CHAR_T *buf;
+    CHAR_T *buf_malloced;
     const CHAR_T *cp;
     size_t i;
     DIRECTIVE *dp;
@@ -152,6 +142,28 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
     size_t allocated;
     size_t length;
 
+    /* Allocate a small buffer that will hold a directive passed to
+       sprintf or snprintf.  */
+    buf_neededlength =
+      xsum4 (7, d.max_width_length, d.max_precision_length, 6);
+#if HAVE_ALLOCA
+    if (buf_neededlength < 4000 / sizeof (CHAR_T))
+      {
+       buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
+       buf_malloced = NULL;
+      }
+    else
+#endif
+      {
+       size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));
+       if (size_overflow_p (buf_memsize))
+         goto out_of_memory_1;
+       buf = (CHAR_T *) malloc (buf_memsize);
+       if (buf == NULL)
+         goto out_of_memory_1;
+       buf_malloced = buf;
+      }
+
     if (resultbuf != NULL)
       {
        result = resultbuf;
@@ -789,7 +801,8 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
                      {
                        if (!(result == resultbuf || result == NULL))
                          free (result);
-                       freea (buf);
+                       if (buf_malloced != NULL)
+                         free (buf_malloced);
                        CLEANUP ();
                        errno = EINVAL;
                        return NULL;
@@ -847,7 +860,8 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
          result = memory;
       }
 
-    freea (buf);
+    if (buf_malloced != NULL)
+      free (buf_malloced);
     CLEANUP ();
     *lengthp = length;
     return result;
@@ -855,7 +869,9 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
   out_of_memory:
     if (!(result == resultbuf || result == NULL))
       free (result);
-    freea (buf);
+    if (buf_malloced != NULL)
+      free (buf_malloced);
+  out_of_memory_1:
     CLEANUP ();
     errno = ENOMEM;
     return NULL;
index 183f96c6b4fc4dfed1c1ff59d10e529655556419..e80a6850c0133c84a51afe517c297950486beb2d 100644 (file)
@@ -1,3 +1,10 @@
+2003-11-17  Bruno Haible  <bruno@clisp.org>
+
+       * vasnprintf.c (alloca): Remove fallback definition.
+       (freea): Remove definition.
+       (VASNPRINTF): Use alloca only for small sizes, say <= 4000 bytes.
+       Reported by Paul Eggert.
+
 2003-11-16  Paul Eggert  <eggert@twinsun.com>
             Bruno Haible  <bruno@clisp.org>
 
index 1415a6f5a8fcb90592c480f45db2970bf7bb6107..05a08bcfb3a23b0e27196054df834a7356b89cb8 100644 (file)
 /* Checked size_t computations.  */
 #include "xsize.h"
 
-/* For those losing systems which don't have 'alloca' we have to add
-   some additional code emulating it.  */
-#ifdef HAVE_ALLOCA
-# define freea(p) /* nothing */
-#else
-# define alloca(n) malloc (n)
-# define freea(p) free (p)
-#endif
-
 #ifdef HAVE_WCHAR_T
 # ifdef HAVE_WCSLEN
 #  define local_wcslen wcslen
@@ -140,10 +131,9 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
     }
 
   {
-    size_t buf_neededlength =
-      xsum4 (7, d.max_width_length, d.max_precision_length, 6);
-    CHAR_T *buf =
-      (CHAR_T *) alloca (xtimes (buf_neededlength, sizeof (CHAR_T)));
+    size_t buf_neededlength;
+    CHAR_T *buf;
+    CHAR_T *buf_malloced;
     const CHAR_T *cp;
     size_t i;
     DIRECTIVE *dp;
@@ -152,6 +142,28 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
     size_t allocated;
     size_t length;
 
+    /* Allocate a small buffer that will hold a directive passed to
+       sprintf or snprintf.  */
+    buf_neededlength =
+      xsum4 (7, d.max_width_length, d.max_precision_length, 6);
+#if HAVE_ALLOCA
+    if (buf_neededlength < 4000 / sizeof (CHAR_T))
+      {
+       buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
+       buf_malloced = NULL;
+      }
+    else
+#endif
+      {
+       size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));
+       if (size_overflow_p (buf_memsize))
+         goto out_of_memory_1;
+       buf = (CHAR_T *) malloc (buf_memsize);
+       if (buf == NULL)
+         goto out_of_memory_1;
+       buf_malloced = buf;
+      }
+
     if (resultbuf != NULL)
       {
        result = resultbuf;
@@ -789,7 +801,8 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
                      {
                        if (!(result == resultbuf || result == NULL))
                          free (result);
-                       freea (buf);
+                       if (buf_malloced != NULL)
+                         free (buf_malloced);
                        CLEANUP ();
                        errno = EINVAL;
                        return NULL;
@@ -847,7 +860,8 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
          result = memory;
       }
 
-    freea (buf);
+    if (buf_malloced != NULL)
+      free (buf_malloced);
     CLEANUP ();
     *lengthp = length;
     return result;
@@ -855,7 +869,9 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
   out_of_memory:
     if (!(result == resultbuf || result == NULL))
       free (result);
-    freea (buf);
+    if (buf_malloced != NULL)
+      free (buf_malloced);
+  out_of_memory_1:
     CLEANUP ();
     errno = ENOMEM;
     return NULL;