jacob said:
Keith Thompson wrote:
.... snip ...
The C standard shows a piece of code that will overflow its static
buffer if used with a year value greater than 8900 (if I remember
correctly)
Similarly, if the month value is greater than 12 it will
show UB.
Obviously, showing such a piece of code is a reminder to the rest
of the world how much the standard cares about buffer overflows.
The discussion in this group confirms this. Look at Mr Thomson:
Absolutely not. I derived the formula for the EXACT size of the
buffer in this discussion group. It is relatively simple. The
only thing that needs to be changed is the "26" in the size of
the buffer.
Nothing needs derivation. The standard adequately specifies
everything. First, see the definition of "struct tm", which
follows:
[#3] The types declared are size_t (described in 7.17);
clock_t
and
time_t
which are arithmetic types capable of representing times;
and
struct tm
which holds the components of a calendar time, called the
broken-down time.
[#4] The tm structure shall contain at least the following
members, in any order. The semantics of the members and
their normal ranges are expressed in the comments.251)
int tm_sec; // seconds after the minute -- [0, 60]
int tm_min; // minutes after the hour -- [0, 59]
int tm_hour; // hours since midnight -- [0, 23]
int tm_mday; // day of the month -- [1, 31]
int tm_mon; // months since January -- [0, 11]
int tm_year; // years since 1900
int tm_wday; // days since Sunday -- [0, 6]
int tm_yday; // days since January 1 -- [0, 365]
int tm_isdst; // Daylight Saving Time flag
The value of tm_isdst is positive if Daylight Saving Time is
in effect, zero if Daylight Saving Time is not in effect,
and negative if the information is not available.
____________________
251The range [0, 60] for tm_sec allows for a positive leap
second.
Note the allowable range for values. Then see the definition for
asctime:
7.23.3.1 The asctime function
Synopsis
[#1]
#include <time.h>
char *asctime(const struct tm *timeptr);
Description
[#2] The asctime function converts the broken-down time in
the structure pointed to by timeptr into a string in the
form
Sun Sep 16 01:03:52 1973\n\0
using the equivalent of the following algorithm.
char *asctime(const struct tm *timeptr) {
static const char wday_name[7][3] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char mon_name[12][3] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static char result[26];
sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
wday_name[timeptr->tm_wday],
mon_name[timeptr->tm_mon],
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
1900 + timeptr->tm_year);
return result;
}
Returns
[#3] The asctime function returns a pointer to the string.
All of which guarantees no overflows for any legitimate value,
provided only that the year does not exceed 9999, or become
negative. Note that there is no buffer for the user to create.
This is intimately connected with the use of the word 'static'.
There is no point to raving about non-existent failings in the C
standard.