Kaydet (Commit) e5b5895b authored tarafından Steve Dower's avatar Steve Dower

Issue #24917: time_strftime() buffer over-read.

üst 714e4937
...@@ -174,6 +174,19 @@ class TimeTestCase(unittest.TestCase): ...@@ -174,6 +174,19 @@ class TimeTestCase(unittest.TestCase):
def test_strftime_bounding_check(self): def test_strftime_bounding_check(self):
self._bounds_checking(lambda tup: time.strftime('', tup)) self._bounds_checking(lambda tup: time.strftime('', tup))
def test_strftime_format_check(self):
# Test that strftime does not crash on invalid format strings
# that may trigger a buffer overread. When not triggered,
# strftime may succeed or raise ValueError depending on
# the platform.
for x in [ '', 'A', '%A', '%AA' ]:
for y in range(0x0, 0x10):
for z in [ '%', 'A%', 'AA%', '%A%', 'A%A%', '%#' ]:
try:
time.strftime(x * y + z)
except ValueError:
pass
def test_default_values_for_zero(self): def test_default_values_for_zero(self):
# Make sure that using all zeros uses the proper default # Make sure that using all zeros uses the proper default
# values. No test for daylight savings since strftime() does # values. No test for daylight savings since strftime() does
......
...@@ -20,6 +20,8 @@ Core and Builtins ...@@ -20,6 +20,8 @@ Core and Builtins
Library Library
------- -------
- Issue #24917: time_strftime() buffer over-read.
- Issue #24748: To resolve a compatibility problem found with py2exe and - Issue #24748: To resolve a compatibility problem found with py2exe and
pywin32, imp.load_dynamic() once again ignores previously loaded modules pywin32, imp.load_dynamic() once again ignores previously loaded modules
to support Python modules replacing themselves with extension modules. to support Python modules replacing themselves with extension modules.
......
...@@ -610,14 +610,15 @@ time_strftime(PyObject *self, PyObject *args) ...@@ -610,14 +610,15 @@ time_strftime(PyObject *self, PyObject *args)
#if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME) #if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME)
/* check that the format string contains only valid directives */ /* check that the format string contains only valid directives */
for(outbuf = strchr(fmt, '%'); for (outbuf = strchr(fmt, '%');
outbuf != NULL; outbuf != NULL;
outbuf = strchr(outbuf+2, '%')) outbuf = strchr(outbuf+2, '%'))
{ {
if (outbuf[1]=='#') if (outbuf[1] == '#')
++outbuf; /* not documented by python, */ ++outbuf; /* not documented by python, */
if ((outbuf[1] == 'y') && buf.tm_year < 0) if (outbuf[1] == '\0')
{ break;
if ((outbuf[1] == 'y') && buf.tm_year < 0) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"format %y requires year >= 1900 on Windows"); "format %y requires year >= 1900 on Windows");
Py_DECREF(format); Py_DECREF(format);
...@@ -625,10 +626,12 @@ time_strftime(PyObject *self, PyObject *args) ...@@ -625,10 +626,12 @@ time_strftime(PyObject *self, PyObject *args)
} }
} }
#elif (defined(_AIX) || defined(sun)) && defined(HAVE_WCSFTIME) #elif (defined(_AIX) || defined(sun)) && defined(HAVE_WCSFTIME)
for(outbuf = wcschr(fmt, '%'); for (outbuf = wcschr(fmt, '%');
outbuf != NULL; outbuf != NULL;
outbuf = wcschr(outbuf+2, '%')) outbuf = wcschr(outbuf+2, '%'))
{ {
if (outbuf[1] == L'\0')
break;
/* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0)) /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0))
returns "0/" instead of "99" */ returns "0/" instead of "99" */
if (outbuf[1] == L'y' && buf.tm_year < 0) { if (outbuf[1] == L'y' && buf.tm_year < 0) {
...@@ -659,7 +662,8 @@ time_strftime(PyObject *self, PyObject *args) ...@@ -659,7 +662,8 @@ time_strftime(PyObject *self, PyObject *args)
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
err = errno; err = errno;
#endif #endif
if (buflen > 0 || i >= 256 * fmtlen) { if (buflen > 0 || fmtlen == 0 ||
(fmtlen > 4 && i >= 256 * fmtlen)) {
/* If the buffer is 256 times as long as the format, /* If the buffer is 256 times as long as the format,
it's probably not failing for lack of room! it's probably not failing for lack of room!
More likely, the format yields an empty result, More likely, the format yields an empty result,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment