tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: snprintf(3) behaviour regarding large "n"



On Wed, Oct 01, 2014 at 01:06:46PM +0200, Steffen Nurpmeso wrote:
 > David Holland <dholland-tech%netbsd.org@localhost> wrote:
 >  |On Mon, Sep 29, 2014 at 09:49:18PM +0200, Steffen Nurpmeso wrote:
 >  |> I just looked at OpenBSD now -- they clamp to INT_MAX if >INT_MAX,
 >  |> which is a much more sane approach that i would also have
 > 
 >  |Problem with that is that there's a lot of code that checks if the
 >  |return value is less than the max size to see if the string (didn't)
 >  |get truncated. So if you clamp the max size, this logic breaks.
 > 
 > Does the function stop processing and return EOVERFLOW if the
 > result would exceed that "int" that is used for the return value,
 > i.e. the actual buffer size?
 > If so, i think you are creating an artificial problem.

It does not:

   snprintf(), vsnprintf(), and vsnprintf_ss() will write at most size-1 of
   the characters printed into the output string (the size'th character then
   gets the terminating `\0'); if the return value is greater than or equal
   to the size argument, the string was too short and some of the printed
   characters were discarded.

 > P.S.: this snippet flew by when i (git) grep'ed in usr.bin for
 >       snprintf(3) usage (gzip/gzip.c) and isn't multibyte safe.
 >       Shall i open a bug report?
 > 
 >                 /* Add (usually) .gz to filename */
 >                 if ((size_t)snprintf(outfile, outsize, "%s%s",
 >                                         file, suffixes[0].zipped) >= outsize)
 >                         memcpy(outfile + outsize - suffixes[0].ziplen - 1,
 >                                 suffixes[0].zipped, suffixes[0].ziplen + 1);

Other than it should check for error in case of EILSEQ, that's more or
less the normal idiom...

-- 
David A. Holland
dholland%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index