[dovecot] Re: vsnprintf()

David Champion dgc at uchicago.edu
Wed Oct 23 20:13:39 EEST 2002


* On 2002.10.23, in <20021023111843.GA3563 at xs4all.nl>,
*	"Thomas Wouters" <thomas at xs4all.net> wrote:
> 
> I think I stumbled upon a bug in the i_snprintf() function. In the case of
> vnsprintf() being available, it depends on vnsprintf() returning -1 when the
> string was longer than the passed-in limit (or it won't terminate the
> string.). But this isn't the C99-standardized behaviour, and newer glibc's
> don't do that anymore either, so you can end up with a non-terminated
> string. This patch should fix it, I think.

Ah, I'm glad glibc has fixed this. (Have they fixed snprintf(), too?)
This patch looks correct for Solaris, as well.

There's an alternative approach that depends on the newer vsnprintf()
behavior. You can use
 
{
	char c, *buf;
	length = vsnprintf(&c, 1, fmt, vp);
	buf = malloc(length+1);
	vsnprintf(buf, length, fmt, vp);
}

to dynamically size the buffer as large as it needs to be. For general
formatting routines, I sometimes use this idiom (not totally valid C,
and no error-checking):

format(...)
{
	static char *buf = NULL;	/* workspace */
	static int buf_len = 0;		/* usable area in buf (size - '\0') */
	int fmt_len;			/* length of formatted string */
	...

	if (buf == NULL) {
		/* init to minimum size */
		buf = malloc(128+1);
		buf_len = 128;
	}

	/* Format once, and find out how long the formatted data was */
	fmt_len = vsnprintf(buf, buf_len+1, fmt, vp);

	/* If longer than buf, resize buf amnd try again */
	if (fmt_len > buf_len) {
		realloc(buf, (buf_len = fmt_len) + 1);
		vsnprintf(buf, buf_len+1, fmt, vp);
	}
	...
}

This makes sure I always have a big-enough buffer, without lots of
unneeded mallocing and freeing. The down-side is that it only works on
modern systems, because of the issue with [v]snprintf()'s return value.
And it sometimes formats the string twice, which is perhaps not good,
but perhaps alright. And I guess it's not re-entrant, which could be a
problem, though it could be made re-entrant with some work. :)


Anyway, this is perhaps a little much for a first post to a list from
someone who hasn't found time to look at or compile the code yet, but
off it goes....

-- 
 -D.                    We establised a fine coffee. What everybody can say
 Sun Project, APC/UCCO  TASTY! It's fresh, so-mild, with some special coffee's
 University of Chicago  bitter and sourtaste. "LET'S HAVE SUCH A COFFEE! NOW!"
 dgc at uchicago.edu       Please love CAFE MIAMI. Many thanks.



More information about the dovecot mailing list