diff options
-rw-r--r-- | Lib/test/test_index.py | 11 | ||||
-rw-r--r-- | Misc/NEWS | 6 | ||||
-rw-r--r-- | Objects/classobject.c | 13 | ||||
-rw-r--r-- | Objects/typeobject.c | 8 |
4 files changed, 25 insertions, 13 deletions
diff --git a/Lib/test/test_index.py b/Lib/test/test_index.py index b224a50..1081b53 100644 --- a/Lib/test/test_index.py +++ b/Lib/test/test_index.py @@ -181,8 +181,8 @@ class OverflowTestCase(unittest.TestCase): self.assertEqual(self.pos.__index__(), self.pos) self.assertEqual(self.neg.__index__(), self.neg) - def test_getitem(self): - class GetItem(object): + def _getitem_helper(self, base): + class GetItem(base): def __len__(self): return maxint def __getitem__(self, key): @@ -195,6 +195,13 @@ class OverflowTestCase(unittest.TestCase): self.assertEqual(x[self.neg:self.pos], (-1, maxint)) self.assertEqual(x[self.neg:self.pos:1].indices(maxint), (0, maxint, 1)) + def test_getitem(self): + self._getitem_helper(object) + + def test_getitem_classic(self): + class Empty: pass + self._getitem_helper(Empty) + def test_sequence_repeat(self): self.failUnlessRaises(OverflowError, lambda: "a" * self.pos) self.failUnlessRaises(OverflowError, lambda: "a" * self.neg) @@ -12,6 +12,12 @@ What's New in Python 2.5 release candidate 1? Core and builtins ----------------- +- Fix bug related to __len__ functions using values > 2**32 on 64-bit machines + with new-style classes. + +- Fix bug related to __len__ functions returning negative values with + classic classes. + - Patch #1538606, Fix __index__() clipping. There were some problems discovered with the API and how integers that didn't fit into Py_ssize_t were handled. This patch attempts to provide enough alternatives diff --git a/Objects/classobject.c b/Objects/classobject.c index 1e93908..e8bac91 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -974,24 +974,25 @@ instance_length(PyInstanceObject *inst) if (res == NULL) return -1; if (PyInt_Check(res)) { - Py_ssize_t temp = PyInt_AsSsize_t(res); - if (temp == -1 && PyErr_Occurred()) { + outcome = PyInt_AsSsize_t(res); + if (outcome == -1 && PyErr_Occurred()) { Py_DECREF(res); return -1; } - outcome = (Py_ssize_t)temp; -#if SIZEOF_SIZE_T < SIZEOF_LONG +#if SIZEOF_SIZE_T < SIZEOF_INT /* Overflow check -- range of PyInt is more than C int */ - if (outcome != temp) { + if (outcome != (int)outcome) { PyErr_SetString(PyExc_OverflowError, "__len__() should return 0 <= outcome < 2**31"); outcome = -1; } else #endif - if (outcome < 0) + if (outcome < 0) { PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); + outcome = -1; + } } else { PyErr_SetString(PyExc_TypeError, diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 517d4db..6edd455 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4110,19 +4110,17 @@ slot_sq_length(PyObject *self) { static PyObject *len_str; PyObject *res = call_method(self, "__len__", &len_str, "()"); - Py_ssize_t temp; Py_ssize_t len; if (res == NULL) return -1; - temp = PyInt_AsSsize_t(res); - len = (int)temp; + len = PyInt_AsSsize_t(res); Py_DECREF(res); if (len == -1 && PyErr_Occurred()) return -1; -#if SIZEOF_SIZE_T < SIZEOF_LONG +#if SIZEOF_SIZE_T < SIZEOF_INT /* Overflow check -- range of PyInt is more than C ssize_t */ - if (len != temp) { + if (len != (int)len) { PyErr_SetString(PyExc_OverflowError, "__len__() should return 0 <= outcome < 2**31"); return -1; |