asctime.c

Robert Elz kre at munnari.OZ.AU
Tue Jul 27 15:48:34 UTC 2004


    Date:        Tue, 27 Jul 2004 10:53:36 -0400
    From:        "Olson, Arthur David (NIH/NCI)" <olsona at dc37a.nci.nih.gov>
    Message-ID:  <75DDD376F2B6B546B722398AC161106C740274 at nihexchange2.nih.gov>

  | Thanks to all for feedback on asctime.c. The version below uses %02.2d for
  | universality, uses %4ld for years to avoid problems if a year isn't four
  | digits long, and avoids the use of snprintf (which isn't available on some
  | systems). There are comments on all these changes. Is it soup yet?

  | 	/*
  | 	** Big enough for something such as
  | 	** ??? ???-2147483648 -2147483648:-2147483648:-2147483648
  | -2147483648\n
  | 	** (two three-character abbreviations, five strings denoting
  | integers,
  | 	** three explicit spaces, two explicit colons, a newline,
  | 	** and a trailing ASCII nul).
  | 	*/
  | 	char			result[2 * 3 + 5 * INT_STRLEN_MAXIMUM(int) +
  | 					3 + 2 + 1 + 1];

That buffer is big enough for that string, but are we sure that string
is the longest that can ever happen?   The year is after all printed
using %ld - so there must at least be the potential for that one to be
a long, which might be -9223372036854775808.

Beyond that, C doesn't actually promise that "int" is limited to 32
bits does it?   Given that, the 2147483648 numbers are just speculation.

Other than validating the input, before conversion to strings, to see
that it will be printable in a reasonable number of characters, snprintf
is really the only good solution.   Where it doesn't exist, just
use a HUGE buffer - it is just stack space after all, make it 1KB, then
no combination of 5 integers is going to overflow it (no-one uses ints
that require 200 digits to represent ... not yet anyway).   Or if you
want to ignore snprintf, always use that BIG buffer.

kre




More information about the tz mailing list