summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorBrett Cannon <bcannon@gmail.com>2004-03-02 04:38:10 (GMT)
committerBrett Cannon <bcannon@gmail.com>2004-03-02 04:38:10 (GMT)
commitd1080a3418b2a162b44d0d5738a6da2276133eb7 (patch)
tree73902ccab6d9c184e726722e1e999fc460b5a90b /Modules
parent0a4977c2f3b8b3cd80f326f44e87076b2578b1b6 (diff)
downloadcpython-d1080a3418b2a162b44d0d5738a6da2276133eb7.zip
cpython-d1080a3418b2a162b44d0d5738a6da2276133eb7.tar.gz
cpython-d1080a3418b2a162b44d0d5738a6da2276133eb7.tar.bz2
Have strftime() check its time tuple argument to make sure the tuple's values
are within proper boundaries as specified in the docs. This can break possible code (datetime module needed changing, for instance) that uses 0 for values that need to be greater 1 or greater (month, day, and day of year). Fixes bug #897625.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/datetimemodule.c4
-rw-r--r--Modules/timemodule.c42
2 files changed, 44 insertions, 2 deletions
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index 3de1c65..c68c368 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -3189,11 +3189,11 @@ time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
* 1900 to worm around that.
*/
tuple = Py_BuildValue("iiiiiiiii",
- 1900, 0, 0, /* year, month, day */
+ 1900, 1, 1, /* year, month, day */
TIME_GET_HOUR(self),
TIME_GET_MINUTE(self),
TIME_GET_SECOND(self),
- 0, 0, -1); /* weekday, daynum, dst */
+ 0, 1, -1); /* weekday, daynum, dst */
if (tuple == NULL)
return NULL;
assert(PyTuple_Size(tuple) == 9);
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index d60f320..ef6ee3e 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -346,6 +346,48 @@ time_strftime(PyObject *self, PyObject *args)
} else if (!gettmarg(tup, &buf))
return NULL;
+ /* 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).
+
+ No check for year since handled in gettmarg().
+ */
+ if (buf.tm_mon < 0 || buf.tm_mon > 11) {
+ PyErr_SetString(PyExc_ValueError, "month out of range");
+ return NULL;
+ }
+ if (buf.tm_mday < 1 || buf.tm_mday > 31) {
+ PyErr_SetString(PyExc_ValueError, "day of month out of range");
+ return NULL;
+ }
+ if (buf.tm_hour < 0 || buf.tm_hour > 23) {
+ PyErr_SetString(PyExc_ValueError, "hour out of range");
+ return NULL;
+ }
+ if (buf.tm_min < 0 || buf.tm_min > 59) {
+ PyErr_SetString(PyExc_ValueError, "minute out of range");
+ return NULL;
+ }
+ if (buf.tm_sec < 0 || buf.tm_sec > 61) {
+ PyErr_SetString(PyExc_ValueError, "seconds out of range");
+ return NULL;
+ }
+ /* tm_wday does not need checking of its upper-bound since taking
+ ``% 7`` in gettmarg() automatically restricts the range. */
+ if (buf.tm_wday < 0) {
+ PyErr_SetString(PyExc_ValueError, "day of week out of range");
+ return NULL;
+ }
+ if (buf.tm_yday < 0 || buf.tm_yday > 365) {
+ PyErr_SetString(PyExc_ValueError, "day of year out of range");
+ return NULL;
+ }
+ if (buf.tm_isdst < -1 || buf.tm_isdst > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "daylight savings flag out of range");
+ return NULL;
+ }
+
fmtlen = strlen(fmt);
/* I hate these functions that presume you know how big the output