]> granicus.if.org Git - python/commitdiff
Issue #22044: Fixed premature DECREF in call_tzinfo_method.
authorRaymond Hettinger <python@rcn.com>
Fri, 25 Jul 2014 21:59:48 +0000 (14:59 -0700)
committerRaymond Hettinger <python@rcn.com>
Fri, 25 Jul 2014 21:59:48 +0000 (14:59 -0700)
Lib/test/datetimetester.py
Misc/ACKS
Misc/NEWS
Modules/_datetimemodule.c

index 3f3c60aceafe68234c147bb3d4092d295ef44e54..cf496b4371a32bdf03c72bffb05bd3f36a378197 100644 (file)
@@ -5,6 +5,7 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
 
 import sys
 import pickle
+import random
 import unittest
 
 from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod
@@ -76,8 +77,18 @@ class PicklableFixedOffset(FixedOffset):
     def __init__(self, offset=None, name=None, dstoffset=None):
         FixedOffset.__init__(self, offset, name, dstoffset)
 
+class _TZInfo(tzinfo):
+    def utcoffset(self, datetime_module):
+        return random.random()
+
 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):
         # In order to allow subclasses to get pickled, the C implementation
         # wasn't able to get away with having __init__ raise
index f7642c88a2021195ef9aba65f894c59b634ac4cc..fdf89d4200ac9653cdf7ea4dceaad00319f71cc8 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -410,6 +410,7 @@ Russell Finn
 Dan Finnie
 Nils Fischbeck
 Frederik Fix
+Tom Flanagan
 Matt Fleming
 Hernán Martínez Foffani
 Artem Fokin
index 8d32544ad59b7f382346a80f0b6278620b799fe4..d580e634023377f989e74c2777ab42076959eb9a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -30,6 +30,9 @@ Library
 - Issue #16133: The asynchat.async_chat.handle_read() method now ignores
   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
   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
index 496ff348f173de257548192304168d5a9f5b367b..d8225bae49065a43b89e94847bef9d0f105e4a32 100644 (file)
@@ -897,11 +897,11 @@ call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg)
         }
     }
     else {
-        Py_DECREF(offset);
         PyErr_Format(PyExc_TypeError,
                      "tzinfo.%s() must return None or "
                      "timedelta, not '%.200s'",
                      name, Py_TYPE(offset)->tp_name);
+        Py_DECREF(offset);
         return NULL;
     }
 
@@ -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
              * code below uses bitwise and operation to check the last
              * bit. */
-           temp = PyNumber_And(x, one);  /* temp <- x & 1 */
+            temp = PyNumber_And(x, one);  /* temp <- x & 1 */
             if (temp == NULL) {
                 Py_DECREF(x);
                 goto Done;
@@ -3224,10 +3224,10 @@ timezone_richcompare(PyDateTime_TimeZone *self,
     if (op != Py_EQ && op != Py_NE)
         Py_RETURN_NOTIMPLEMENTED;
     if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
-       if (op == Py_EQ)
-           Py_RETURN_FALSE;
-       else
-           Py_RETURN_TRUE;
+        if (op == Py_EQ)
+            Py_RETURN_FALSE;
+        else
+            Py_RETURN_TRUE;
     }
     return delta_richcompare(self->offset, other->offset, op);
 }
@@ -4814,7 +4814,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
     static char *keywords[] = {"tz", NULL};
 
     if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
-                                     &tzinfo))
+                                      &tzinfo))
         return NULL;
 
     if (check_tzinfo_subclass(tzinfo) == -1)