From 8c28ddb1561655229c9c5a7e30b92b4da963855a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 9 Jun 2023 21:41:30 +0200 Subject: [PATCH 1/3] gh-105375: Improve error handling in _ctypes Prevent repeated PyLong_FromVoidPtr() from possibly overwriting the current exception. --- ...23-06-09-21-40-45.gh-issue-105375._sZilh.rst | 1 + Modules/_ctypes/callbacks.c | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-06-09-21-40-45.gh-issue-105375._sZilh.rst diff --git a/Misc/NEWS.d/next/Library/2023-06-09-21-40-45.gh-issue-105375._sZilh.rst b/Misc/NEWS.d/next/Library/2023-06-09-21-40-45.gh-issue-105375._sZilh.rst new file mode 100644 index 00000000000000..87db4c2b4e22e3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-06-09-21-40-45.gh-issue-105375._sZilh.rst @@ -0,0 +1 @@ +Fix bugs in :mod:`_ctypes` where exceptions could end up being overwritten. diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 8e694ba852c1d4..09353d4ab33887 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -479,13 +479,20 @@ long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid); + if (py_rclsid == NULL) { + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } PyObject *py_riid = PyLong_FromVoidPtr((void *)riid); + if (py_riid == NULL) { + Py_DECREF(py_rclsid); + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } PyObject *py_ppv = PyLong_FromVoidPtr(ppv); - if (!py_rclsid || !py_riid || !py_ppv) { - Py_XDECREF(py_rclsid); - Py_XDECREF(py_riid); - Py_XDECREF(py_ppv); - Py_DECREF(func); + if (py_ppv == NULL) { + Py_DECREF(py_rclsid); + Py_DECREF(py_riid); PyErr_WriteUnraisable(context ? context : Py_None); return E_FAIL; } From 00461fa7a8ae1c1b1679155209815b1ca420a95a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 11 Jun 2023 12:26:28 +0200 Subject: [PATCH 2/3] Address review: also decref func --- Modules/_ctypes/callbacks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 09353d4ab33887..e29b265046c6fc 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -480,17 +480,20 @@ long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid); if (py_rclsid == NULL) { + Py_DECREF(func); PyErr_WriteUnraisable(context ? context : Py_None); return E_FAIL; } PyObject *py_riid = PyLong_FromVoidPtr((void *)riid); if (py_riid == NULL) { + Py_DECREF(func); Py_DECREF(py_rclsid); PyErr_WriteUnraisable(context ? context : Py_None); return E_FAIL; } PyObject *py_ppv = PyLong_FromVoidPtr(ppv); if (py_ppv == NULL) { + Py_DECREF(func); Py_DECREF(py_rclsid); Py_DECREF(py_riid); PyErr_WriteUnraisable(context ? context : Py_None); From 26fd23d47026f0f0bea2c69765c4092ea90eea6c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 11 Jun 2023 21:19:51 +0200 Subject: [PATCH 3/3] Slightly reduce diff in GH view --- Modules/_ctypes/callbacks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index e29b265046c6fc..d71297f9c5c2f2 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -493,9 +493,9 @@ long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) } PyObject *py_ppv = PyLong_FromVoidPtr(ppv); if (py_ppv == NULL) { - Py_DECREF(func); Py_DECREF(py_rclsid); Py_DECREF(py_riid); + Py_DECREF(func); PyErr_WriteUnraisable(context ? context : Py_None); return E_FAIL; }