diff -r c27f3282fd98 -r e6fe80fd0c77 Modules/timemodule.c --- a/Modules/timemodule.c Thu Sep 23 23:40:30 2010 +0900 +++ b/Modules/timemodule.c Fri Sep 24 10:17:52 2010 +0900 @@ -345,6 +345,7 @@ Convert seconds since the Epoch to a time tuple expressing local time.\n\ When 'seconds' is not passed in, convert the current time instead."); +/* Convert 9-item tuple to tm structure */ static int gettmarg(PyObject *args, struct tm *p) { @@ -388,32 +389,33 @@ return 1; } +/* Checks added to make sure strftime(), asctime() does not crash Python by + indexing blindly into some array for a textual representation + by some bad index (fixes bug #897625, #6608). + + Also support values of zero from Python code for arguments in which + that is out of range by forcing that value to the lowest value that + is valid (fixed bug #1520914). + + Valid ranges based on what is allowed in struct tm: + + - tm_year: [0, max(int)] (1) + - tm_mon: [0, 11] (2) + - tm_mday: [1, 31] + - tm_hour: [0, 23] + - tm_min: [0, 59] + - tm_sec: [0, 60] + - tm_wday: [0, 6] (1) + - tm_yday: [0, 365] (2) + - tm_isdst: [-max(int), max(int)] + + (1) gettmarg() handles bounds-checking. + (2) Python's acceptable range is one greater than the range in C, + thus need to check against automatic decrement by gettmarg(). +*/ static int -is_valid_tm(struct tm* buf) { - /* Checks added to make sure strftime() does not crash Python by - indexing blindly into some array for a textual representation - by some bad index (fixes bug #897625). - - Also support values of zero from Python code for arguments in which - that is out of range by forcing that value to the lowest value that - is valid (fixed bug #1520914). - - Valid ranges based on what is allowed in struct tm: - - - tm_year: [0, max(int)] (1) - - tm_mon: [0, 11] (2) - - tm_mday: [1, 31] - - tm_hour: [0, 23] - - tm_min: [0, 59] - - tm_sec: [0, 60] - - tm_wday: [0, 6] (1) - - tm_yday: [0, 365] (2) - - tm_isdst: [-max(int), max(int)] - - (1) gettmarg() handles bounds-checking. - (2) Python's acceptable range is one greater than the range in C, - thus need to check against automatic decrement by gettmarg(). - */ +checktm(struct tm* buf) +{ if (buf->tm_mon == -1) buf->tm_mon = 0; else if (buf->tm_mon < 0 || buf->tm_mon > 11) { @@ -472,7 +474,7 @@ if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); - } else if (!gettmarg(tup, &buf) || !is_valid_tm(&buf)) + } else if (!gettmarg(tup, &buf) || !checktm(&buf)) return NULL; /* Normalize tm_isdst just in case someone foolishly implements %Z @@ -574,7 +576,7 @@ if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); - } else if (!gettmarg(tup, &buf) || !is_valid_tm(&buf)) + } else if (!gettmarg(tup, &buf) || !checktm(&buf)) return NULL; p = asctime(&buf);