X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fsnprintf.c;h=db1ca9af1e7c2ab4e9f0a55073f5345dfe76084a;hb=c1c022da45f67cf61e9993a08b5a80a6f30578bb;hp=92c265289a3730865150acb7c9781092b9f555cf;hpb=edafda534244e3760000faf7a088af872d146325;p=gnulib.git diff --git a/lib/snprintf.c b/lib/snprintf.c index 92c265289..db1ca9af1 100644 --- a/lib/snprintf.c +++ b/lib/snprintf.c @@ -1,6 +1,6 @@ /* Formatted output to strings. - Copyright (C) 2004 Free Software Foundation, Inc. - Written by Simon Josefsson. + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + Written by Simon Josefsson and Paul Eggert. 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 @@ -14,27 +14,24 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifdef HAVE_CONFIG_H -# include -#endif +#include -/* Specification. */ #include "snprintf.h" -/* Get va_list, va_start, va_end. */ +#include +#include #include -/* Get free. */ #include -/* Get memcpy, size_t. */ #include -/* Get vasnprintf. */ #include "vasnprintf.h" -/* Get MIN. */ -#include "minmax.h" +/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */ +#ifndef EOVERFLOW +# define EOVERFLOW E2BIG +#endif /* Print formatted output to string STR. Similar to sprintf, but additional length SIZE limit how much is written into STR. Returns @@ -46,22 +43,34 @@ snprintf (char *str, size_t size, const char *format, ...) { char *output; size_t len; + size_t lenbuf = size; va_list args; va_start (args, format); - output = vasnprintf (NULL, &len, format, args); + output = vasnprintf (str, &lenbuf, format, args); + len = lenbuf; va_end (args); if (!output) return -1; - if (str) + if (output != str) { - memcpy (str, output, MIN (len + 1, size)); - str[size - 1] = '\0'; + if (size) + { + size_t pruned_len = (len < size ? len : size - 1); + memcpy (str, output, pruned_len); + str[pruned_len] = '\0'; + } + + free (output); } - free (output); + if (INT_MAX < len) + { + errno = EOVERFLOW; + return -1; + } return len; }