diff options
author | Jelle Zijlstra <jelle.zijlstra@gmail.com> | 2023-05-12 05:22:40 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-12 05:22:40 (GMT) |
commit | a0a98ddb31591357bead4694b21717cb4034924f (patch) | |
tree | 05269c152cc5a41d126dba845faaa2f08d726657 /Objects | |
parent | ac66cc17f21653b66321b50d0a1f792982fca21f (diff) | |
download | cpython-a0a98ddb31591357bead4694b21717cb4034924f.zip cpython-a0a98ddb31591357bead4694b21717cb4034924f.tar.gz cpython-a0a98ddb31591357bead4694b21717cb4034924f.tar.bz2 |
gh-104371: Fix calls to `__release_buffer__` while an exception is active (#104378)
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f1745c9..f40e197 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -9117,6 +9117,12 @@ releasebuffer_maybe_call_super(PyObject *self, Py_buffer *buffer) static void releasebuffer_call_python(PyObject *self, Py_buffer *buffer) { + // bf_releasebuffer may be called while an exception is already active. + // We have no way to report additional errors up the stack, because + // this slot returns void, so we simply stash away the active exception + // and restore it after the call to Python returns. + PyObject *exc = PyErr_GetRaisedException(); + PyObject *mv; bool is_buffer_wrapper = Py_TYPE(buffer->obj) == &_PyBufferWrapper_Type; if (is_buffer_wrapper) { @@ -9124,7 +9130,7 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer) // __release_buffer__() that __buffer__() returned. PyBufferWrapper *bw = (PyBufferWrapper *)buffer->obj; if (bw->mv == NULL) { - return; + goto end; } mv = Py_NewRef(bw->mv); } @@ -9134,7 +9140,7 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer) mv = PyMemoryView_FromBuffer(buffer); if (mv == NULL) { PyErr_WriteUnraisable(self); - return; + goto end; } // Set the memoryview to restricted mode, which forbids // users from saving any reference to the underlying buffer @@ -9155,6 +9161,10 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer) PyObject_CallMethodNoArgs(mv, &_Py_ID(release)); } Py_DECREF(mv); +end: + assert(!PyErr_Occurred()); + + PyErr_SetRaisedException(exc); } /* |