Submitter: Stoughton (US)
     Submission Date: 2006-03-28
     
     Source: The Austin Group
     Reference Document:  
    AI-053.txt, DR 217
     Version: 1.3
     Date:2007-09-06
     Subject: asctime()
Summary: asctime() tm_year gt
    9999
This is a potential defect forwarded from the Austin Group.
If asctime() is called with a tm
    structure whose tm_year field results in a
    year > 9999 (which is possible with 64-bit
    time_t), the current specification of
    asctime() would result in
    asctime() to overrunning a 26-character
    buffer; the specification says the
    sprintf() format for printing the year is
    "%d", and (eg) a 5-digit number would print 5 characters,
    overrunning the buffer.
Similarly, since the user can create the input
    struct tm, it is possible for the user to
    set the fields of the struct tm to values
    that are outside the normal bounds. In such a case, the
    sprintf() format given in the
    asctime() specification can result in a
    buffer overrun. For example, if tm_hour is
    100, the sprintf()
    format .2d writes the string "100", which
    could result in a buffer overrun. The specification should be
    updated to state the algorithm can be used as long as the
    values of the tm struct are restricted to
    the normal bounds.
Suggested Technical Corrigendum
    
Change 7.23.3.1 para 2 from:
      The asctime function converts the broken-down time in the
      structure pointed to by timeptr into a
      string in the form:
    
    To: 
    The(NB, see 7.23.1 para 4 for the specifications of the "normal ranges").asctime()function shall convert the broken-down time in the structure pointed to bytimeptrinto a string in the form, provided the broken-down time in the fields of the structure pointed to bytimeptrcontain values that are within the normal ranges as defined in<time.h>, and the calculated year does not exceed four digits:
Also, add after the example code, and before the "Returns" section, the following new paragraph:
Otherwise, if any of the fields of thetmstructure pointed to bytimeptrcontain values that are outside the normal ranges, the behavior ofasctime()is undefined. If the calculated year exceeds four digits, the behavior is undefined.
Committee Discussion (for history only)
The proposed resolution invalidates code that strictly conforms to the C99 standard. Here is a contrived example (though there are some examples that are not contrived):
   #include <time.h>
   #include <stdio.h>
   struct tm tm;
   int
   main (void)
   {
     tm.tm_wday = 0;
     tm.tm_mon = 0;
     tm.tm_mday = -99;
     tm.tm_hour = 99;
     tm.tm_min = 99;
     tm.tm_sec = 99;
     tm.tm_year = -999 - 1900;
     printf ("%s\n", asctime (&tm));
     return 0;
   }
    This code strictly conforms to C99, with well-defined behavior, and some implementations prints "Sun Jan-99 99:99:99 -999". The proposed resolution places extra constraints on asctime's arguments that would cause the above code to have undefined behavior.
The original interpretation request considered by the Austin Group contained an additional requirement, that the calculated year should not precede the Epoch (the date and time associated with (time_t)0). This restriction was removed in forwarding this to the C committee, since there is no C equivalent concept. However, if the calculated year is less than 1000, problems may occur, so perhaps the wording should be:
If the calculated year is less than 1000 or greater than 9999, the behavior is undefined.
Note: This appears to be a duplicate of DR 217, which advises no consensus / no change.
It was also pointed out that the Proposed Technical
    Corrigendum does not fix all of the issues, such as if
    tm_mon=4 and
    tm_mday=31, both valid numbers, but not a
    valid date.
Technical Corrigendum
    
Add after the example code, and before the "Returns" section, the following new paragraph:
If any of the fields of theAdd footnote *:tmstructure pointed to bytimeptrcontain values that are outside the normal ranges*, the behavior ofasctime()is undefined. If the calculated year exceeds four digits, or is less than the year 1000, the behavior is undefined.
See 7.23.1 para 4 for the specifications of the "normal ranges".Previous Defect Report < - > Next Defect Report