From 1603759a255989329c90da90fc14f8bd4aa351a6 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 9 Jun 2023 23:35:06 +0200 Subject: [PATCH 1/6] gh-105375: Improve PyErr_WarnExplicit() error handling Bail on first error to prevent exceptions from possibly being overwritten. --- .../C API/2023-06-09-23-34-25.gh-issue-105375.n7amiF.rst | 2 ++ Python/_warnings.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2023-06-09-23-34-25.gh-issue-105375.n7amiF.rst diff --git a/Misc/NEWS.d/next/C API/2023-06-09-23-34-25.gh-issue-105375.n7amiF.rst b/Misc/NEWS.d/next/C API/2023-06-09-23-34-25.gh-issue-105375.n7amiF.rst new file mode 100644 index 00000000000000..b9f95496f938ec --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-06-09-23-34-25.gh-issue-105375.n7amiF.rst @@ -0,0 +1,2 @@ +Fix a bug in :c:func:`PyErr_WarnExplicit` where an exception could end up +being overwritten if the API failed internally. diff --git a/Python/_warnings.c b/Python/_warnings.c index 69fa04e6befe18..0f691f35cb8345 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1298,12 +1298,16 @@ PyErr_WarnExplicit(PyObject *category, const char *text, const char *module_str, PyObject *registry) { PyObject *message = PyUnicode_FromString(text); + if (message == NULL) { + goto exit; + } PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + goto exit; + } PyObject *module = NULL; int ret = -1; - if (message == NULL || filename == NULL) - goto exit; if (module_str != NULL) { module = PyUnicode_FromString(module_str); if (module == NULL) From 7fe31c2ecd13d8938ef4837b4f2e9768d55eae8d Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 10 Jun 2023 22:30:40 +0200 Subject: [PATCH 2/6] Fix maybe-uinitialized warning --- Python/_warnings.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Python/_warnings.c b/Python/_warnings.c index 0f691f35cb8345..b716659aeb61b7 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1306,22 +1306,20 @@ PyErr_WarnExplicit(PyObject *category, const char *text, goto exit; } PyObject *module = NULL; - int ret = -1; - if (module_str != NULL) { module = PyUnicode_FromString(module_str); if (module == NULL) goto exit; } - ret = PyErr_WarnExplicitObject(category, message, filename, lineno, - module, registry); + return PyErr_WarnExplicitObject(category, message, filename, lineno, + module, registry); exit: Py_XDECREF(message); Py_XDECREF(module); Py_XDECREF(filename); - return ret; + return -1; } int From 91c7c6cd16defd8a1b06c9c3de321dbd8734f73a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 10 Jun 2023 22:33:34 +0200 Subject: [PATCH 3/6] 'module' can also be uninitialized --- Python/_warnings.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Python/_warnings.c b/Python/_warnings.c index b716659aeb61b7..7869787da25160 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1312,12 +1312,13 @@ PyErr_WarnExplicit(PyObject *category, const char *text, goto exit; } - return PyErr_WarnExplicitObject(category, message, filename, lineno, - module, registry); + int ret = PyErr_WarnExplicitObject(category, message, filename, lineno, + module, registry); + Py_XDECREF(module); + return ret; exit: Py_XDECREF(message); - Py_XDECREF(module); Py_XDECREF(filename); return -1; } From d05d7407bec123be114cd00713d6bf327f940696 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 10 Jun 2023 22:34:15 +0200 Subject: [PATCH 4/6] Don't 'goto exit' for the first error check --- Python/_warnings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/_warnings.c b/Python/_warnings.c index 7869787da25160..efeaaeb847ee44 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1299,7 +1299,7 @@ PyErr_WarnExplicit(PyObject *category, const char *text, { PyObject *message = PyUnicode_FromString(text); if (message == NULL) { - goto exit; + return NULL; } PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); if (filename == NULL) { From 5c5100ab683e4559bd3dfd0cbc3166541243e531 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 10 Jun 2023 22:38:44 +0200 Subject: [PATCH 5/6] Rewrite it --- Python/_warnings.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Python/_warnings.c b/Python/_warnings.c index efeaaeb847ee44..db66adc815ec21 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1299,28 +1299,27 @@ PyErr_WarnExplicit(PyObject *category, const char *text, { PyObject *message = PyUnicode_FromString(text); if (message == NULL) { - return NULL; + return -1; } PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); if (filename == NULL) { - goto exit; + Py_DECREF(message); + return -1; } PyObject *module = NULL; if (module_str != NULL) { module = PyUnicode_FromString(module_str); - if (module == NULL) - goto exit; + if (module == NULL) { + Py_DECREF(filename); + Py_DECREF(message); + return -1; + } } int ret = PyErr_WarnExplicitObject(category, message, filename, lineno, module, registry); Py_XDECREF(module); return ret; - - exit: - Py_XDECREF(message); - Py_XDECREF(filename); - return -1; } int From b7f3245cfc1ab53cf2bd0799fbaad1f02e05f11b Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 10 Jun 2023 22:39:33 +0200 Subject: [PATCH 6/6] Also decref 'message' and 'filename' --- Python/_warnings.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Python/_warnings.c b/Python/_warnings.c index db66adc815ec21..465cbf9bd3039a 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1319,6 +1319,8 @@ PyErr_WarnExplicit(PyObject *category, const char *text, int ret = PyErr_WarnExplicitObject(category, message, filename, lineno, module, registry); Py_XDECREF(module); + Py_DECREF(filename); + Py_DECREF(message); return ret; }