Commit 5a2146a2 authored by Raymond Hettinger's avatar Raymond Hettinger

Issue #22044: Fixed premature DECREF in call_tzinfo_method.

parent 65dd69a3
...@@ -5,6 +5,7 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases ...@@ -5,6 +5,7 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
import sys import sys
import pickle import pickle
import random
import unittest import unittest
from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod
...@@ -76,8 +77,18 @@ class PicklableFixedOffset(FixedOffset): ...@@ -76,8 +77,18 @@ class PicklableFixedOffset(FixedOffset):
def __init__(self, offset=None, name=None, dstoffset=None): def __init__(self, offset=None, name=None, dstoffset=None):
FixedOffset.__init__(self, offset, name, dstoffset) FixedOffset.__init__(self, offset, name, dstoffset)
class _TZInfo(tzinfo):
def utcoffset(self, datetime_module):
return random.random()
class TestTZInfo(unittest.TestCase): class TestTZInfo(unittest.TestCase):
def test_refcnt_crash_bug_22044(self):
tz1 = _TZInfo()
dt1 = datetime(2014, 7, 21, 11, 32, 3, 0, tz1)
with self.assertRaises(TypeError):
dt1.utcoffset()
def test_non_abstractness(self): def test_non_abstractness(self):
# In order to allow subclasses to get pickled, the C implementation # In order to allow subclasses to get pickled, the C implementation
# wasn't able to get away with having __init__ raise # wasn't able to get away with having __init__ raise
......
...@@ -410,6 +410,7 @@ Russell Finn ...@@ -410,6 +410,7 @@ Russell Finn
Dan Finnie Dan Finnie
Nils Fischbeck Nils Fischbeck
Frederik Fix Frederik Fix
Tom Flanagan
Matt Fleming Matt Fleming
Hernán Martínez Foffani Hernán Martínez Foffani
Artem Fokin Artem Fokin
......
...@@ -30,6 +30,9 @@ Library ...@@ -30,6 +30,9 @@ Library
- Issue #16133: The asynchat.async_chat.handle_read() method now ignores - Issue #16133: The asynchat.async_chat.handle_read() method now ignores
BlockingIOError exceptions. BlockingIOError exceptions.
- Issue #22044: Fixed premature DECREF in call_tzinfo_method.
Patch by Tom Flanagan.
- Issue #19884: readline: Disable the meta modifier key if stdout is not - Issue #19884: readline: Disable the meta modifier key if stdout is not
a terminal to not write the ANSI sequence "\033[1034h" into stdout. This a terminal to not write the ANSI sequence "\033[1034h" into stdout. This
sequence is used on some terminal (ex: TERM=xterm-256color") to enable sequence is used on some terminal (ex: TERM=xterm-256color") to enable
......
...@@ -897,11 +897,11 @@ call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg) ...@@ -897,11 +897,11 @@ call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg)
} }
} }
else { else {
Py_DECREF(offset);
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"tzinfo.%s() must return None or " "tzinfo.%s() must return None or "
"timedelta, not '%.200s'", "timedelta, not '%.200s'",
name, Py_TYPE(offset)->tp_name); name, Py_TYPE(offset)->tp_name);
Py_DECREF(offset);
return NULL; return NULL;
} }
...@@ -2153,7 +2153,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) ...@@ -2153,7 +2153,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
* is odd. Note that x is odd when it's last bit is 1. The * is odd. Note that x is odd when it's last bit is 1. The
* code below uses bitwise and operation to check the last * code below uses bitwise and operation to check the last
* bit. */ * bit. */
temp = PyNumber_And(x, one); /* temp <- x & 1 */ temp = PyNumber_And(x, one); /* temp <- x & 1 */
if (temp == NULL) { if (temp == NULL) {
Py_DECREF(x); Py_DECREF(x);
goto Done; goto Done;
...@@ -3224,10 +3224,10 @@ timezone_richcompare(PyDateTime_TimeZone *self, ...@@ -3224,10 +3224,10 @@ timezone_richcompare(PyDateTime_TimeZone *self,
if (op != Py_EQ && op != Py_NE) if (op != Py_EQ && op != Py_NE)
Py_RETURN_NOTIMPLEMENTED; Py_RETURN_NOTIMPLEMENTED;
if (Py_TYPE(other) != &PyDateTime_TimeZoneType) { if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
if (op == Py_EQ) if (op == Py_EQ)
Py_RETURN_FALSE; Py_RETURN_FALSE;
else else
Py_RETURN_TRUE; Py_RETURN_TRUE;
} }
return delta_richcompare(self->offset, other->offset, op); return delta_richcompare(self->offset, other->offset, op);
} }
...@@ -4814,7 +4814,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) ...@@ -4814,7 +4814,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
static char *keywords[] = {"tz", NULL}; static char *keywords[] = {"tz", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords, if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
&tzinfo)) &tzinfo))
return NULL; return NULL;
if (check_tzinfo_subclass(tzinfo) == -1) if (check_tzinfo_subclass(tzinfo) == -1)
......
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