Bugtraq mailing list archives

Re: better snprintf replacement, anyone?


From: deraadt () CVS OPENBSD ORG (Theo de Raadt)
Date: Tue, 22 Jul 1997 16:45:12 -0600


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).

Incredible Peter -- you've proved the point far better than I could
have. (What a disgusting, complicated, overworked, and error-prone
mess).

I would prefer to just analyze what happens when a truncation occurs,
and decide how to deal with that:

        if (snprintf(buf, sizeof buf, %s %d see %d %lx %s %s\n",
            a, i, j, p, b, c) >= sizeof buf)
                /* deal with the buffer truncation */

However, in most cases truncation is OK.



Current thread: