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

erlend-aasland webhook-mailer at python.org
Tue Jun 13 05:15:28 EDT 2023


https://github.com/python/cpython/commit/56877e4560821ad00cabe6253448c1c938cfed59
commit: 56877e4560821ad00cabe6253448c1c938cfed59
branch: 3.12
author: Erlend E. Aasland <erlend.aasland at protonmail.com>
committer: erlend-aasland <erlend.aasland at protonmail.com>
date: 2023-06-13T09:15:19Z
summary:

[3.12] gh-105375: Improve error handling in _Unpickler_SetInputStream() (#105667) (#105720)

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

(cherry picked from commit 217589d4f3246d67c6ef0eb0be2b1c33987cf260)

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 688bccbab6b4..d2f6d71059ea 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