strcat+strcat+strcat == baaad
winehebhaim at sun.consumer.org.il
Mon Dec 2 03:55:28 CST 2002
David Laight wrote:
>>you were underestimating the time required to parse the format string,
>>which is probably greater than anything else. Everything else is simple
>>searching and copying whereas the parsing is probably at least a
>No it will be linear (on the length of the format string).
>But just rather more expensive than you probably expect.
That's the reason that I thought it will be faster. However, since the
test program copied 40 bytes 10 times, which is a rather extreme case,
and still was not faster, we can only conclude that sprinf is not
practical for almost all standard cases.
>There is a lot of red tape lurking.
This, however, does not answer the usability issue. Obviously, we won't
put in patches that convert to anything else just because someone didn't
like it (yes, I agree with Alexander on this point). There is, however,
the question of buffer overruns.
I suggest implementing strlcat and strlcpy, as in OpenBSD. I can write
them, but I'm not sure where to place them. They should either be
inlined (as in - implemented in an include file as a static func), or in
some library that will be linked (statically, I hope). Ideas?
For those who don't know strl* functions - they are just like strn*
functions, except that the parameters are sane:
* Resulting string is not always NULL terminated.
* In strncat, the terminating null is always written, but is not
counted in the size!!!
* The size parameter is sometimes the total size of the buffer, and
sometimes the size of the unused portion of the buffer.
* On strncpy, the entire buffer is written into, even if very little
of it is needed (performance)
All of the above make for awkward and error prone coding. In order to
use strncat properly, you have to keep subtracting the number of
characters already copied, and 1 for the terminating nul. As a result of
these subtractions, a negative overflow (i.e. - from 0 to maxint) may
happen, which in turn causes buffer overruns itself.
Unlike it, in the strl* functions:
* Resulting string is ALWAYS NULL terminated, whether there was
enough room or not.
* The buffer is not padded with NULLs beyond the terminating one
* The number is ALWAYS the total buffer size. No arithmetics are
More information about the wine-devel