[2206] in bugtraq
Re: syslog()/snprintf(): beware of functions with fuzzy specs
daemon@ATHENA.MIT.EDU (Casper Dik)
Wed Sep 6 22:44:08 1995
Date: Wed, 6 Sep 1995 16:39:10 +0200
Reply-To: Bugtraq List <BUGTRAQ@CRIMELAB.COM>
From: Casper Dik <casper@Holland.Sun.COM>
X-To: Bugtraq List <BUGTRAQ@CRIMELAB.COM>
To: Multiple recipients of list BUGTRAQ <BUGTRAQ@CRIMELAB.COM>
In-Reply-To: Your message of "Fri, 01 Sep 1995 17:23:53 PDT."
<199509020023.RAA29501@teal.us.oracle.com>
>BSD4.4 snprintf()s return the number of characters they would have
>written had the buffer been infinite. This is despite the manual page
>saying they return the number of characters actually written.
This should be fixed. It requires the *snprintf() code to parse
and examine all arguments: that isn't necessary.
And p += snprintf(p, &buf[sizeof(buf)] -p, ...)
won't work as expected.
>Number of characters written does not include the NULL.
(Aside: I prefer NUL to refer to '\0' and NULL to refer to the null pointer)
>GNU snprintf()s return the number of characters actually written (minus
>the NULL). On a overflowed buffer, the GNU documentation conflicts with
>itself. At one point it says, (bufsiz - 1) is returned, and in another
>example it says (bufsiz) is returned (but (bufsiz - 1) plus a NULL
>character are written). I'm not sure what it does for real.
I'm pretty sure we want a terminated string. I.e., return "bufsiz - 1".
>I've seen a few other cobbled version of *nprintf. I'm best off with a
>dart board if I needed to apriori determine what they do on the boundary
>cases.
>
>Some important boundary cases:
>
>vsnprintf (buf, bufsiz, fmt, ap)
>
> bufsiz = 0
> bufsiz = 1
> bufsiz = amount of chars sprint will use, less one for the null
> bufsiz = amount of chars sprint will use, no room for null
> bufsiz = less than amount of chars sprint will use
>
>Which return values of -1, 0, bufsiz - 1, bufsiz, or >bufsiz (heaven
>forbid a core dump)? Do they write on buf[bufsiz]? What do they write
>to buf? What is the state of NULL terminatation on each of the
>sitations above? Many different answers have I seen.
snsprintf should never write buf[bufsize], it can write buf[bufsize-1].
I prefer the following:
bufsiz strsize return value
0 N/A 0 (can argue in favour of -1)
1 N/A 0
>1 <bufsiz strsize
>1 >=bufsiz bufsiz-1
It can be argued that snprintf(buf, 0, ...) should return -1: there's
no room for the '\0'.
But you also want p += snprintf(....) to continue to work.
(But note that if you do that properly, the remaining number of bytes
will never drop below 1)
>For those of you working on syslog patches using *nprintf, you will do
>the world a favor if you make it explicitly clear the semantics you
>expect.
Or ignore the return value and use strlen(). (In which case you
depend on snprintf to return '\0' terminated strings.)
Casper