120 lines
4.1 KiB
Diff
120 lines
4.1 KiB
Diff
--- 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
|
|
+ <http://www.gnu.org/licenses/>. */
|
|
|
|
#include <ctype.h>
|
|
#include <limits.h>
|
|
@@ -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;
|
|
}
|