diff options
author | Raymond Hettinger <python@rcn.com> | 2009-02-02 21:50:13 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2009-02-02 21:50:13 (GMT) |
commit | b516370bcbeef7391edc28fa6bfcc8da6d98beea (patch) | |
tree | 057c3efe6e2de33086e1762a5a17d68384368eb0 /Objects | |
parent | d7bb4d484ff0adb0f40e34ed316e58e8a4b88a9e (diff) | |
download | cpython-b516370bcbeef7391edc28fa6bfcc8da6d98beea.zip cpython-b516370bcbeef7391edc28fa6bfcc8da6d98beea.tar.gz cpython-b516370bcbeef7391edc28fa6bfcc8da6d98beea.tar.bz2 |
Issue 1242657: list(obj) can swallow KeyboardInterrupt.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 33 | ||||
-rw-r--r-- | Objects/bytearrayobject.c | 4 | ||||
-rw-r--r-- | Objects/listobject.c | 4 |
3 files changed, 27 insertions, 14 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 0d6aa4a..1ac4ac9 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -85,8 +85,8 @@ PyObject_Length(PyObject *o) /* The length hint function returns a non-negative value from o.__len__() or o.__length_hint__(). If those methods aren't found or return a negative - value, then the defaultvalue is returned. This function never fails. - Accordingly, it will mask exceptions raised in either method. + value, then the defaultvalue is returned. If one of the calls fails, + this function returns -1. */ Py_ssize_t @@ -100,29 +100,32 @@ _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) rv = PyObject_Size(o); if (rv >= 0) return rv; - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_TypeError) && + !PyErr_ExceptionMatches(PyExc_AttributeError)) + return -1; PyErr_Clear(); + } /* cache a hashed version of the attribute string */ if (hintstrobj == NULL) { hintstrobj = PyString_InternFromString("__length_hint__"); if (hintstrobj == NULL) - goto defaultcase; + return -1; } /* try o.__length_hint__() */ ro = PyObject_CallMethodObjArgs(o, hintstrobj, NULL); - if (ro == NULL) - goto defaultcase; + if (ro == NULL) { + if (!PyErr_ExceptionMatches(PyExc_TypeError) && + !PyErr_ExceptionMatches(PyExc_AttributeError)) + return -1; + PyErr_Clear(); + return defaultvalue; + } rv = PyInt_AsLong(ro); Py_DECREF(ro); - if (rv >= 0) - return rv; - -defaultcase: - if (PyErr_Occurred()) - PyErr_Clear(); - return defaultvalue; + return rv; } PyObject * @@ -2128,7 +2131,7 @@ PySequence_Tuple(PyObject *v) { PyObject *it; /* iter(v) */ Py_ssize_t n; /* guess for result tuple size */ - PyObject *result; + PyObject *result = NULL; Py_ssize_t j; if (v == NULL) @@ -2153,6 +2156,8 @@ PySequence_Tuple(PyObject *v) /* Guess result size and allocate space. */ n = _PyObject_LengthHint(v, 10); + if (n == -1) + goto Fail; result = PyTuple_New(n); if (result == NULL) goto Fail; diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 4b8d585..4cfd9f8 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2691,6 +2691,10 @@ bytes_extend(PyByteArrayObject *self, PyObject *arg) /* Try to determine the length of the argument. 32 is abitrary. */ buf_size = _PyObject_LengthHint(arg, 32); + if (buf_size == -1) { + Py_DECREF(it); + return NULL; + } bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size); if (bytes_obj == NULL) diff --git a/Objects/listobject.c b/Objects/listobject.c index 7b4bf35..98d7e47 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -838,6 +838,10 @@ listextend(PyListObject *self, PyObject *b) /* Guess a result list size. */ n = _PyObject_LengthHint(b, 8); + if (n == -1) { + Py_DECREF(it); + return NULL; + } m = Py_SIZE(self); mn = m + n; if (mn >= m) { |