[Python-checkins] gh-105375: Improve error handling in _Unpickler_SetInputStream() (#105667)

erlend-aasland webhook-mailer at python.org
Tue Jun 13 04:38:10 EDT 2023


https://github.com/python/cpython/commit/217589d4f3246d67c6ef0eb0be2b1c33987cf260
commit: 217589d4f3246d67c6ef0eb0be2b1c33987cf260
branch: main
author: Erlend E. Aasland <erlend.aasland at protonmail.com>
committer: erlend-aasland <erlend.aasland at protonmail.com>
date: 2023-06-13T10:38:01+02:00
summary:

gh-105375: Improve error handling in _Unpickler_SetInputStream() (#105667)

Prevent exceptions from possibly being overwritten in case of multiple
failures.

files:
A Misc/NEWS.d/next/Library/2023-06-11-22-46-06.gh-issue-105375.YkhSNt.rst
M Modules/_pickle.c

diff --git a/Misc/NEWS.d/next/Library/2023-06-11-22-46-06.gh-issue-105375.YkhSNt.rst b/Misc/NEWS.d/next/Library/2023-06-11-22-46-06.gh-issue-105375.YkhSNt.rst
new file mode 100644
index 000000000000..dda8f428760b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-06-11-22-46-06.gh-issue-105375.YkhSNt.rst
@@ -0,0 +1,2 @@
+Fix a bug in :c:func:`!_Unpickler_SetInputStream` where an exception could
+end up being overwritten in case of failure.
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 9e70fee84e18..4913a8dfee58 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -1694,25 +1694,30 @@ _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file)
 {
     /* Optional file methods */
     if (_PyObject_LookupAttr(file, &_Py_ID(peek), &self->peek) < 0) {
-        return -1;
+        goto error;
     }
     if (_PyObject_LookupAttr(file, &_Py_ID(readinto), &self->readinto) < 0) {
-        return -1;
+        goto error;
+    }
+    if (_PyObject_LookupAttr(file, &_Py_ID(read), &self->read) < 0) {
+        goto error;
+    }
+    if (_PyObject_LookupAttr(file, &_Py_ID(readline), &self->readline) < 0) {
+        goto error;
     }
-    (void)_PyObject_LookupAttr(file, &_Py_ID(read), &self->read);
-    (void)_PyObject_LookupAttr(file, &_Py_ID(readline), &self->readline);
     if (!self->readline || !self->read) {
-        if (!PyErr_Occurred()) {
-            PyErr_SetString(PyExc_TypeError,
-                            "file must have 'read' and 'readline' attributes");
-        }
-        Py_CLEAR(self->read);
-        Py_CLEAR(self->readinto);
-        Py_CLEAR(self->readline);
-        Py_CLEAR(self->peek);
-        return -1;
+        PyErr_SetString(PyExc_TypeError,
+                        "file must have 'read' and 'readline' attributes");
+        goto error;
     }
     return 0;
+
+error:
+    Py_CLEAR(self->read);
+    Py_CLEAR(self->readinto);
+    Py_CLEAR(self->readline);
+    Py_CLEAR(self->peek);
+    return -1;
 }
 
 /* Returns -1 (with an exception set) on failure, 0 on success. This may



More information about the Python-checkins mailing list