Bugtraq mailing list archives
Re: better snprintf replacement, anyone?
From: mouse () RODENTS MONTREAL QC CA (der Mouse)
Date: Tue, 22 Jul 1997 21:27:31 -0400
The point beyond which a system is so legacy it's not worth even trying to support it, for me, includes systems without calls like snprintf.Sun would probably not be totally pleased with having Solaris 2.5.1(*) referred to as a legacy OS.
I really don't give a damn what Sun is or isn't pleased with. Any vendor that's too sluggish to have implemented such rudimentary security measures as implementing functions like snprintf that border on essential for writing reasonably secure code deserves no sympathy. Hell, even back when I was working on 4.3 I'd hacked in fopenstr(), which opened a string buffer (including length) and returned a FILE * to which I/O could be done, which amounts to much the same thing. It took me all of maybe half an hour. Even with all the inefficiency and overhead associated with being a big software house, I have trouble seeing it taking more than one person-day. There even is a complete stdio package - including snprintf - available free, even to people like commercial software vendors; they have no excuse. None.
Let me give you an example of what you suggest:
if (strlen(a) + 1 + 10 + 3 + 1 + 10 + 4*sizeof(long) + 1 + strlen(b) + 1 + strlen(c) + 2 >= sizeof buf); sprintf(buf, "%s %d see %d %lx %s %s\n", a, i, j, p, b, c);
As a comment to support Theo's point of view, it's worth noting that the above example includes about 6 errors. [...]
It may or may not, depending on how much the programmer knew about the values the (presumably int) variables printed with %d could take on, and how machine-dependent the code is. Specifically, it assumes - that i and j occupy no more than nine digits each when printed with %d - that the sizeof() unit occupies no more than 4 characters when printed as part of %lx In addition, the way the arithmetic is done implies that the format string is quite different from what it actually is; I had to look carefully to get the figure "nine" in the above.
#define N_DEC_DIGIT(type) ((((sizeof(type) * 8 - 1) * 30103 + 99999) \ / 100000) + 1)
8? You should be using CHAR_BIT. I normally use the equivalent of #define N_DEC_DIGIT(type) (((CHAR_BIT*sizeof(type))/3)+2) on the theory that it requires no more digits in decimal than in octal, plus a sign, plus no more than one digit lost to divison round-down. (Overestimating is less serious than underestimating; since most values will be much less than the maximum, it's an overestimate anyway.)
(For those puzzled about N_DEC_DIGIT: log10(2) ~= .30103 and the sign bit doesn't count).
You're assuming there is a sign bit. (Signed) int may be represented in other ways, such as a negative-base representation, or maybe even something like BCD. (Note also that log(2) < .30103, so your #define will underestimate the number of digits. Fortunately (for you :-), the rounding-up-to-an-integer part salvages the situation unless sizeof(type) is quite implausibly huge.) Actually, the "smaller than the maximum" note above is a reason to use snprintf rather than estimating. When I write something like snprintf(buf,"%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", i, j, tbl[i], tbl[j], tbl[tbl[i]+tbl[j]], .... n, count_interesting_entries(tbl,n)); most of the numbers will usually be one or two digits, maybe three or four, not eight or nine. If I'm mallocking a buffer, this is not particularly serious, but if I'm doing "goto bail" or moral equivalent on apparent overflow, it is. der Mouse mouse () rodents montreal qc ca 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Current thread:
- Security hole in exim 1.62: local root exploit, (continued)
- Security hole in exim 1.62: local root exploit Aleph One (Jul 22)
- Re: Security hole in exim 1.62: local root exploit Warner Losh (Jul 22)
- Named Config Files Gus Huber (Jul 22)
- Re: Named Config Files Aveek Datta (Jul 22)
- Security hole in exim 1.62: local root exploit Aleph One (Jul 22)
- Re: better snprintf replacement, anyone? Bill Rugolsky Jr. (Jul 22)
- Re: better snprintf replacement, anyone? Casper Dik (Jul 23)
- Re: better snprintf replacement, anyone? der Mouse (Jul 22)
- Re: better snprintf replacement, anyone? Sten Gunterberg (Jul 22)
- Re: better snprintf replacement, anyone? Peter Jeremy (Jul 22)
- Re: better snprintf replacement, anyone? Theo de Raadt (Jul 22)
- Re: better snprintf replacement, anyone? der Mouse (Jul 22)