[4983] in bugtraq

home help back first fref pref prev next nref lref last post

Re: better snprintf replacement, anyone?

daemon@ATHENA.MIT.EDU (Peter Jeremy)
Tue Jul 22 18:04:24 1997

Date: 	Wed, 23 Jul 1997 07:30:22 +1000
Reply-To: Peter Jeremy <peter.jeremy@ALCATEL.COM.AU>
From: Peter Jeremy <peter.jeremy@ALCATEL.COM.AU>
To: BUGTRAQ@NETSPACE.ORG

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

home help back first fref pref prev next nref lref last post