+2006-10-08 Bruno Haible <bruno@clisp.org>
+
+ * printf.c: Include errno.h, limits.h.
+ (EOVERFLOW): New fallback definition.
+ (libintl_vfprintf): Test whether the output length is > INT_MAX.
+ (libintl_vsprintf): Likewise.
+ (libintl_vsnprintf): Fix bug when vasnprintf requested more space than
+ needed. Fix return value when the entire result string would be larger
+ than the provided buffer. Test whether the output length is > INT_MAX.
+ (libintl_vasprintf): Test whether the output length is > INT_MAX.
+ (libintl_vfwprintf): Likewise.
+ (libintl_vswprintf): Fix bug when vasnwprintf requested more space than
+ needed. Test whether the output length is > INT_MAX.
+
2006-09-14 Bruno Haible <bruno@clisp.org>
* lock.c: Include <config.h> unconditionally.
#if !HAVE_POSIX_PRINTF
+#include <errno.h>
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
+/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
+#ifndef EOVERFLOW
+# define EOVERFLOW E2BIG
+#endif
+
/* When building a DLL, we must export some functions. Note that because
the functions are only defined for binary backward compatibility, we
don't need to use __declspec(dllimport) in any case. */
int retval = -1;
if (result != NULL)
{
- if (fwrite (result, 1, length, stream) == length)
- retval = length;
+ size_t written = fwrite (result, 1, length, stream);
free (result);
+ if (written == length)
+ {
+ if (length > INT_MAX)
+ errno = EOVERFLOW;
+ else
+ retval = length;
+ }
}
return retval;
}
free (result);
return -1;
}
+ if (length > INT_MAX)
+ {
+ errno = EOVERFLOW;
+ return -1;
+ }
else
return length;
}
{
if (maxlength > 0)
{
- if (length < maxlength)
- abort ();
- memcpy (resultbuf, result, maxlength - 1);
- resultbuf[maxlength - 1] = '\0';
+ size_t pruned_length =
+ (length < maxlength ? length : maxlength - 1);
+ memcpy (resultbuf, result, pruned_length);
+ resultbuf[pruned_length] = '\0';
}
free (result);
+ }
+ if (length > INT_MAX)
+ {
+ errno = EOVERFLOW;
return -1;
}
else
char *result = libintl_vasnprintf (NULL, &length, format, args);
if (result == NULL)
return -1;
+ if (length > INT_MAX)
+ {
+ free (result);
+ errno = EOVERFLOW;
+ return -1;
+ }
*resultp = result;
return length;
}
for (i = 0; i < length; i++)
if (fputwc (result[i], stream) == WEOF)
break;
- if (i == length)
- retval = length;
free (result);
+ if (i == length)
+ {
+ if (length > INT_MAX)
+ errno = EOVERFLOW;
+ else
+ retval = length;
+ }
}
return retval;
}
{
if (maxlength > 0)
{
- if (length < maxlength)
- abort ();
- memcpy (resultbuf, result, (maxlength - 1) * sizeof (wchar_t));
- resultbuf[maxlength - 1] = 0;
+ size_t pruned_length =
+ (length < maxlength ? length : maxlength - 1);
+ memcpy (resultbuf, result, pruned_length * sizeof (wchar_t));
+ resultbuf[pruned_length] = 0;
}
free (result);
+ /* Unlike vsnprintf, which has to return the number of character that
+ would have been produced if the resultbuf had been sufficiently
+ large, the vswprintf function has to return a negative value if
+ the resultbuf was not sufficiently large. */
+ if (length >= maxlength)
+ return -1;
+ }
+ if (length > INT_MAX)
+ {
+ errno = EOVERFLOW;
return -1;
}
else