mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-05 00:37:59 +02:00
Cope with platforms whose vsnprintf violates both POSIX and C99
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=11668 Reviewed-by: Will Thompson <will.thompson@collabora.co.uk>
This commit is contained in:
parent
029ecdf402
commit
7fc9c02666
1 changed files with 49 additions and 3 deletions
|
|
@ -3021,14 +3021,60 @@ _dbus_full_duplex_pipe (int *fd1,
|
|||
*
|
||||
* @param format a printf-style format string
|
||||
* @param args arguments for the format string
|
||||
* @returns length of the given format string and args
|
||||
* @returns length of the given format string and args, or -1 if no memory
|
||||
*/
|
||||
int
|
||||
_dbus_printf_string_upper_bound (const char *format,
|
||||
va_list args)
|
||||
{
|
||||
char c;
|
||||
return vsnprintf (&c, 1, format, args);
|
||||
char static_buf[1024];
|
||||
int bufsize = sizeof (static_buf);
|
||||
int len;
|
||||
|
||||
len = vsnprintf (static_buf, bufsize, format, args);
|
||||
|
||||
/* If vsnprintf() returned non-negative, then either the string fits in
|
||||
* static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
|
||||
* returns the number of characters that were needed, or this OS returns the
|
||||
* truncated length.
|
||||
*
|
||||
* We ignore the possibility that snprintf might just ignore the length and
|
||||
* overrun the buffer (64-bit Solaris 7), because that's pathological.
|
||||
* If your libc is really that bad, come back when you have a better one. */
|
||||
if (len == bufsize)
|
||||
{
|
||||
/* This could be the truncated length (Tru64 and IRIX have this bug),
|
||||
* or the real length could be coincidentally the same. Which is it?
|
||||
* If vsnprintf returns the truncated length, we'll go to the slow
|
||||
* path. */
|
||||
if (vsnprintf (static_buf, 1, format, args) == 1)
|
||||
len = -1;
|
||||
}
|
||||
|
||||
/* If vsnprintf() returned negative, we have to do more work.
|
||||
* HP-UX returns negative. */
|
||||
while (len < 0)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
bufsize *= 2;
|
||||
|
||||
buf = dbus_malloc (bufsize);
|
||||
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
len = vsnprintf (buf, bufsize, format, args);
|
||||
dbus_free (buf);
|
||||
|
||||
/* If the reported length is exactly the buffer size, round up to the
|
||||
* next size, in case vsnprintf has been returning the truncated
|
||||
* length */
|
||||
if (len == bufsize)
|
||||
len = -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue