Skip to content

Commit 2b1745f

Browse files
[3.11] gh-105375: Improve error handling in _Unpickler_SetInputStream() (#105667) (#105721)
Prevent exceptions from possibly being overwritten in case of multiple failures. (cherry picked from commit 217589d)
1 parent 36c393c commit 2b1745f

File tree

2 files changed

+20
-13
lines changed

2 files changed

+20
-13
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a bug in :c:func:`!_Unpickler_SetInputStream` where an exception could
2+
end up being overwritten in case of failure.

Modules/_pickle.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,25 +1666,30 @@ _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file)
16661666
{
16671667
/* Optional file methods */
16681668
if (_PyObject_LookupAttr(file, &_Py_ID(peek), &self->peek) < 0) {
1669-
return -1;
1669+
goto error;
16701670
}
16711671
if (_PyObject_LookupAttr(file, &_Py_ID(readinto), &self->readinto) < 0) {
1672-
return -1;
1672+
goto error;
1673+
}
1674+
if (_PyObject_LookupAttr(file, &_Py_ID(read), &self->read) < 0) {
1675+
goto error;
1676+
}
1677+
if (_PyObject_LookupAttr(file, &_Py_ID(readline), &self->readline) < 0) {
1678+
goto error;
16731679
}
1674-
(void)_PyObject_LookupAttr(file, &_Py_ID(read), &self->read);
1675-
(void)_PyObject_LookupAttr(file, &_Py_ID(readline), &self->readline);
16761680
if (!self->readline || !self->read) {
1677-
if (!PyErr_Occurred()) {
1678-
PyErr_SetString(PyExc_TypeError,
1679-
"file must have 'read' and 'readline' attributes");
1680-
}
1681-
Py_CLEAR(self->read);
1682-
Py_CLEAR(self->readinto);
1683-
Py_CLEAR(self->readline);
1684-
Py_CLEAR(self->peek);
1685-
return -1;
1681+
PyErr_SetString(PyExc_TypeError,
1682+
"file must have 'read' and 'readline' attributes");
1683+
goto error;
16861684
}
16871685
return 0;
1686+
1687+
error:
1688+
Py_CLEAR(self->read);
1689+
Py_CLEAR(self->readinto);
1690+
Py_CLEAR(self->readline);
1691+
Py_CLEAR(self->peek);
1692+
return -1;
16881693
}
16891694

16901695
/* Returns -1 (with an exception set) on failure, 0 on success. This may

0 commit comments

Comments
 (0)