summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend.aasland@protonmail.com>2023-06-13 08:38:01 (GMT)
committerGitHub <noreply@github.com>2023-06-13 08:38:01 (GMT)
commit217589d4f3246d67c6ef0eb0be2b1c33987cf260 (patch)
tree1725243cb9341c0c19b6e6bcca6711a65607dcf0
parent840d02f3f0cd341207db6d918ce7f0987be9952e (diff)
downloadcpython-217589d4f3246d67c6ef0eb0be2b1c33987cf260.zip
cpython-217589d4f3246d67c6ef0eb0be2b1c33987cf260.tar.gz
cpython-217589d4f3246d67c6ef0eb0be2b1c33987cf260.tar.bz2
gh-105375: Improve error handling in _Unpickler_SetInputStream() (#105667)
Prevent exceptions from possibly being overwritten in case of multiple failures.
-rw-r--r--Misc/NEWS.d/next/Library/2023-06-11-22-46-06.gh-issue-105375.YkhSNt.rst2
-rw-r--r--Modules/_pickle.c31
2 files changed, 20 insertions, 13 deletions
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 0000000..dda8f42
--- /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 9e70fee..4913a8d 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