bpo-29953: Fix memory leaks in the replace() method of datetime and t… (#933)

objects when pass out of bound fold argument.
(cherry picked from commit 314d6fca36)
This commit is contained in:
Serhiy Storchaka 2017-03-31 23:23:49 +03:00 committed by GitHub
parent 0a17e58446
commit 7d5d13d8d0
3 changed files with 18 additions and 11 deletions

View File

@ -4313,6 +4313,11 @@ class TestLocalTimeDisambiguation(unittest.TestCase):
dt = dt.replace(fold=1, tzinfo=Eastern) dt = dt.replace(fold=1, tzinfo=Eastern)
self.assertEqual(t.replace(tzinfo=None).fold, 1) self.assertEqual(t.replace(tzinfo=None).fold, 1)
self.assertEqual(dt.replace(tzinfo=None).fold, 1) self.assertEqual(dt.replace(tzinfo=None).fold, 1)
# Out of bounds.
with self.assertRaises(ValueError):
t.replace(fold=2)
with self.assertRaises(ValueError):
dt.replace(fold=2)
# Check that fold is a keyword-only argument # Check that fold is a keyword-only argument
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
t.replace(1, 1, 1, None, 1) t.replace(1, 1, 1, None, 1)

View File

@ -30,6 +30,9 @@ Core and Builtins
Library Library
------- -------
- bpo-29953: Fixed memory leaks in the replace() method of datetime and time
objects when pass out of bound fold argument.
- bpo-29942: Fix a crash in itertools.chain.from_iterable when encountering - bpo-29942: Fix a crash in itertools.chain.from_iterable when encountering
long runs of empty iterables. long runs of empty iterables.

View File

@ -3926,16 +3926,16 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
time_kws, time_kws,
&hh, &mm, &ss, &us, &tzinfo, &fold)) &hh, &mm, &ss, &us, &tzinfo, &fold))
return NULL; return NULL;
tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
if (tuple == NULL)
return NULL;
clone = time_new(Py_TYPE(self), tuple, NULL);
if (clone != NULL) {
if (fold != 0 && fold != 1) { if (fold != 0 && fold != 1) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"fold must be either 0 or 1"); "fold must be either 0 or 1");
return NULL; return NULL;
} }
tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
if (tuple == NULL)
return NULL;
clone = time_new(Py_TYPE(self), tuple, NULL);
if (clone != NULL) {
TIME_SET_FOLD(clone, fold); TIME_SET_FOLD(clone, fold);
} }
Py_DECREF(tuple); Py_DECREF(tuple);
@ -5019,17 +5019,16 @@ datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
&y, &m, &d, &hh, &mm, &ss, &us, &y, &m, &d, &hh, &mm, &ss, &us,
&tzinfo, &fold)) &tzinfo, &fold))
return NULL; return NULL;
tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
if (tuple == NULL)
return NULL;
clone = datetime_new(Py_TYPE(self), tuple, NULL);
if (clone != NULL) {
if (fold != 0 && fold != 1) { if (fold != 0 && fold != 1) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"fold must be either 0 or 1"); "fold must be either 0 or 1");
return NULL; return NULL;
} }
tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
if (tuple == NULL)
return NULL;
clone = datetime_new(Py_TYPE(self), tuple, NULL);
if (clone != NULL) {
DATE_SET_FOLD(clone, fold); DATE_SET_FOLD(clone, fold);
} }
Py_DECREF(tuple); Py_DECREF(tuple);