--- a/stdio-common/vfprintf.c 2012-03-07 12:16:21.000000000 -0700
+++ b/stdio-common/vfprintf.c 2012-03-07 12:00:28.006630851 -0700
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2011, 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -12,9 +12,8 @@
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ . */
#include
#include
@@ -823,7 +822,7 @@ vfprintf (FILE *s, const CHAR_T *format,
\
if (function_done < 0) \
{ \
- /* Error in print handler. */ \
+ /* Error in print handler; up to handler to set errno. */ \
done = -1; \
goto all_done; \
} \
@@ -877,7 +876,7 @@ vfprintf (FILE *s, const CHAR_T *format,
\
if (function_done < 0) \
{ \
- /* Error in print handler. */ \
+ /* Error in print handler; up to handler to set errno. */ \
done = -1; \
goto all_done; \
} \
@@ -1118,7 +1117,7 @@ vfprintf (FILE *s, const CHAR_T *format,
&mbstate); \
if (len == (size_t) -1) \
{ \
- /* Something went wron gduring the conversion. Bail out. */ \
+ /* Something went wrong during the conversion. Bail out. */ \
done = -1; \
goto all_done; \
} \
@@ -1574,6 +1606,7 @@ vfprintf (FILE *s, const CHAR_T *format,
if (spec == L_('\0'))
{
/* The format string ended before the specifier is complete. */
+ __set_errno (EINVAL);
done = -1;
goto all_done;
}
@@ -1671,29 +1704,34 @@ do_positional:
/* Determine the number of arguments the format string consumes. */
nargs = MAX (nargs, max_ref_arg);
- bytes_per_arg = sizeof (*args_value) + sizeof (*args_size)
- + sizeof (*args_type);
+ /* Calculate total size needed to represent a single argument across
+ all three argument-related arrays. */
+ bytes_per_arg = (sizeof (*args_value) + sizeof (*args_size)
+ + sizeof (*args_type));
/* Check for potential integer overflow. */
- if (nargs > SIZE_MAX / bytes_per_arg)
+ if (__builtin_expect (nargs > SIZE_MAX / bytes_per_arg, 0))
{
- done = -1;
- goto all_done;
+ __set_errno (ERANGE);
+ done = -1;
+ goto all_done;
}
- /* Allocate memory for the argument descriptions. */
+ /* Allocate memory for all three argument arrays. */
if (__libc_use_alloca (nargs * bytes_per_arg))
- args_value = alloca (nargs * bytes_per_arg);
+ args_value = alloca (nargs * bytes_per_arg);
else
{
- args_value = args_malloced = malloc (nargs * bytes_per_arg);
- if (args_value == NULL)
- {
- done = -1;
- goto all_done;
- }
+ args_value = args_malloced = malloc (nargs * bytes_per_arg);
+ if (args_value == NULL)
+ {
+ done = -1;
+ goto all_done;
+ }
}
+ /* Set up the remaining two arrays to each point past the end of the
+ prior array, since space for all three has been allocated now. */
args_size = &args_value[nargs].pa_int;
args_type = &args_size[nargs];
memset (args_type, s->_flags2 & _IO_FLAGS2_FORTIFY ? '\xff' : '\0',
@@ -1912,6 +1950,7 @@ do_positional:
about # of chars. */
if (function_done < 0)
{
+ /* Function has set errno. */
done = -1;
goto all_done;
}
@@ -1946,6 +1985,7 @@ do_positional:
of chars. */
if (function_done < 0)
{
+ /* Function has set errno. */
done = -1;
goto all_done;
}