Bugtraq mailing list archives

Re: better snprintf replacement, anyone?


From: peter.jeremy () ALCATEL COM AU (Peter Jeremy)
Date: Wed, 23 Jul 1997 07:30:22 +1000


On Tue, 22 Jul 1997 10:19:54 -0400, der Mouse <mouse () RODENTS MONTREAL QC CA>
wrote:
My reaction to this is "not using punched cards makes it hard to port
to (other) legacy systems".  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 don't have ready access to other
current commercial C libraries.  There's also the problem that (as far
as I know) [v]snprintf() is not part of the Standard C Library.

(*) Solaris 2.5.1 does include [v]snprintf, but only as `private'
    routines with non-standard names.  The routines weren't present
    at all prior to Solaris 2.5.

On Tue, 22 Jul 1997 00:57:11 -0600, Theo de Raadt <deraadt () CVS OPENBSD ORG>
wrote:
On 22nd July, Steve Coile wrote:
I would imagine that there are only a few cases were a program coulnd't
pre-determine the length of a string that would be generated by sprintf()
and malloc() enough memory to contain it all.

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);
       else
               goto bail; /* I really just wanted to truncate the string... */

As a comment to support Theo's point of view, it's worth noting that
the above example includes about 6 errors.  I realize Theo probably
whipped it up off the top of his head, but it does demonstrate the
difficulty of this approach.  It should be something like:

#define N_DEC_DIGIT(type)       ((((sizeof(type) * 8 - 1) * 30103 + 99999) \
                                 / 100000) + 1)

        if (strlen(a) + 1 + N_DEC_DIGIT(int) + 5 + N_DEC_DIGIT(int) + 1 +
            2*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);
        } else {
                goto bail; /* I really just wanted to truncate the string... */
        }

(For those puzzled about N_DEC_DIGIT: log10(2) ~= .30103 and the sign bit
doesn't count).

Peter
---
Peter Jeremy (VK2PJ)                    peter.jeremy () alcatel com au
Alcatel Australia Limited
41 Mandible St                          Phone: +61 2 9690 5019
ALEXANDRIA  NSW  2015                   Fax:   +61 2 9690 5247



Current thread: