]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-105375: Improve error handling in _Unpickler_SetInputStream() (#105667...
authorErlend E. Aasland <erlend.aasland@protonmail.com>
Tue, 13 Jun 2023 09:15:19 +0000 (11:15 +0200)
committerGitHub <noreply@github.com>
Tue, 13 Jun 2023 09:15:19 +0000 (09:15 +0000)
Prevent exceptions from possibly being overwritten in case of multiple
failures.

(cherry picked from commit 217589d4f3246d67c6ef0eb0be2b1c33987cf260)

Misc/NEWS.d/next/Library/2023-06-11-22-46-06.gh-issue-105375.YkhSNt.rst [new file with mode: 0644]
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 (file)
index 0000000..dda8f42
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a bug in :c:func:`!_Unpickler_SetInputStream` where an exception could
+end up being overwritten in case of failure.
index 688bccbab6b4a821bdac01085a5f7050d150d9c5..d2f6d71059ea00a57aea5aaf942611eccf62b996 100644 (file)
@@ -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