diff -r 4969057df0b1 -r c27f3282fd98 Modules/timemodule.c --- a/Modules/timemodule.c Wed Sep 22 07:45:14 2010 +0200 +++ b/Modules/timemodule.c Thu Sep 23 23:40:30 2010 +0900 @@ -388,28 +388,8 @@ return 1; } -#ifdef HAVE_STRFTIME -static PyObject * -time_strftime(PyObject *self, PyObject *args) -{ - PyObject *tup = NULL; - struct tm buf; - const char *fmt; - size_t fmtlen, buflen; - char *outbuf = 0; - size_t i; - - memset((void *) &buf, '\0', sizeof(buf)); - - if (!PyArg_ParseTuple(args, "s|O:strftime", &fmt, &tup)) - return NULL; - - if (tup == NULL) { - time_t tt = time(NULL); - buf = *localtime(&tt); - } else if (!gettmarg(tup, &buf)) - return NULL; - +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). @@ -434,42 +414,67 @@ (2) Python's acceptable range is one greater than the range in C, thus need to check against automatic decrement by gettmarg(). */ - if (buf.tm_mon == -1) - buf.tm_mon = 0; - else if (buf.tm_mon < 0 || buf.tm_mon > 11) { + if (buf->tm_mon == -1) + buf->tm_mon = 0; + else if (buf->tm_mon < 0 || buf->tm_mon > 11) { PyErr_SetString(PyExc_ValueError, "month out of range"); - return NULL; + return 0; } - if (buf.tm_mday == 0) - buf.tm_mday = 1; - else if (buf.tm_mday < 0 || buf.tm_mday > 31) { + if (buf->tm_mday == 0) + buf->tm_mday = 1; + else if (buf->tm_mday < 0 || buf->tm_mday > 31) { PyErr_SetString(PyExc_ValueError, "day of month out of range"); - return NULL; + return 0; } - if (buf.tm_hour < 0 || buf.tm_hour > 23) { + if (buf->tm_hour < 0 || buf->tm_hour > 23) { PyErr_SetString(PyExc_ValueError, "hour out of range"); - return NULL; + return 0; } - if (buf.tm_min < 0 || buf.tm_min > 59) { + if (buf->tm_min < 0 || buf->tm_min > 59) { PyErr_SetString(PyExc_ValueError, "minute out of range"); - return NULL; + return 0; } - if (buf.tm_sec < 0 || buf.tm_sec > 61) { + if (buf->tm_sec < 0 || buf->tm_sec > 61) { PyErr_SetString(PyExc_ValueError, "seconds out of range"); - return NULL; + return 0; } /* tm_wday does not need checking of its upper-bound since taking ``% 7`` in gettmarg() automatically restricts the range. */ - if (buf.tm_wday < 0) { + if (buf->tm_wday < 0) { PyErr_SetString(PyExc_ValueError, "day of week out of range"); + return 0; + } + if (buf->tm_yday == -1) + buf->tm_yday = 0; + else if (buf->tm_yday < 0 || buf->tm_yday > 365) { + PyErr_SetString(PyExc_ValueError, "day of year out of range"); + return 0; + } + return 1; +} + +#ifdef HAVE_STRFTIME +static PyObject * +time_strftime(PyObject *self, PyObject *args) +{ + PyObject *tup = NULL; + struct tm buf; + const char *fmt; + size_t fmtlen, buflen; + char *outbuf = 0; + size_t i; + + memset((void *) &buf, '\0', sizeof(buf)); + + if (!PyArg_ParseTuple(args, "s|O:strftime", &fmt, &tup)) return NULL; - } - if (buf.tm_yday == -1) - buf.tm_yday = 0; - else if (buf.tm_yday < 0 || buf.tm_yday > 365) { - PyErr_SetString(PyExc_ValueError, "day of year out of range"); + + if (tup == NULL) { + time_t tt = time(NULL); + buf = *localtime(&tt); + } else if (!gettmarg(tup, &buf) || !is_valid_tm(&buf)) return NULL; - } + /* Normalize tm_isdst just in case someone foolishly implements %Z based on the assumption that tm_isdst falls within the range of [-1, 1] */ @@ -569,8 +574,9 @@ if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); - } else if (!gettmarg(tup, &buf)) + } else if (!gettmarg(tup, &buf) || !is_valid_tm(&buf)) return NULL; + p = asctime(&buf); if (p[24] == '\n') p[24] = '\0';