X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fvsprintf.c;h=dbe1fbc1c3c814bb28abc4564b7d97033efac4e7;hb=23eecb48e39afd0d267d64d40ba6bf97aa865e13;hp=f75f510bc568ebf41c606fe76bb185b37424ff16;hpb=9148e4d7d455e2624f43f4048652f77e11ec88cd;p=gnulib.git
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index f75f510bc..dbe1fbc1c 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1,19 +1,18 @@
/* Formatted output to strings.
- Copyright (C) 2004, 2006-2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006-2013 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
+ 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
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
#ifdef HAVE_CONFIG_H
# include
@@ -25,28 +24,34 @@
#include
#include
#include
+#include
#include
#include "vasnprintf.h"
-/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
-#ifndef EOVERFLOW
-# define EOVERFLOW E2BIG
-#endif
-
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
/* Print formatted output to string STR.
Return string length of formatted string. On error, return a negative
- value. */
+ value. */
int
vsprintf (char *str, const char *format, va_list args)
{
char *output;
size_t len;
- size_t lenbuf = SIZE_MAX;
+ size_t lenbuf;
+
+ /* vasnprintf fails with EOVERFLOW when the buffer size argument is larger
+ than INT_MAX (if that fits into a 'size_t' at all).
+ Also note that glibc's iconv fails with E2BIG when we pass a length that
+ is so large that str + lenbuf wraps around, i.e.
+ (uintptr_t) (str + lenbuf) < (uintptr_t) str.
+ Therefore set lenbuf = min (SIZE_MAX, INT_MAX, - (uintptr_t) str - 1). */
+ lenbuf = (SIZE_MAX < INT_MAX ? SIZE_MAX : INT_MAX);
+ if (lenbuf > ~ (uintptr_t) str)
+ lenbuf = ~ (uintptr_t) str;
output = vasnprintf (str, &lenbuf, format, args);
len = lenbuf;