--- 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; }