summaryrefslogtreecommitdiffstats
path: root/Python/errors.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2025-02-25 21:04:27 (GMT)
committerGitHub <noreply@github.com>2025-02-25 21:04:27 (GMT)
commit0ef4ffeefd1737c18dc9326133c7894d58108c2e (patch)
treedc3614077d06e68df192e57505951b80012a2e31 /Python/errors.c
parent2dad1e08ec9d5ddc798a313900613b3d1eeaff6b (diff)
downloadcpython-0ef4ffeefd1737c18dc9326133c7894d58108c2e.zip
cpython-0ef4ffeefd1737c18dc9326133c7894d58108c2e.tar.gz
cpython-0ef4ffeefd1737c18dc9326133c7894d58108c2e.tar.bz2
gh-130163: Fix crashes related to PySys_GetObject() (GH-130503)
The use of PySys_GetObject() and _PySys_GetAttr(), which return a borrowed reference, has been replaced by using one of the following functions, which return a strong reference and distinguish a missing attribute from an error: _PySys_GetOptionalAttr(), _PySys_GetOptionalAttrString(), _PySys_GetRequiredAttr(), and _PySys_GetRequiredAttrString().
Diffstat (limited to 'Python/errors.c')
-rw-r--r--Python/errors.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/Python/errors.c b/Python/errors.c
index 0a19d89..bf48c10 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -8,7 +8,7 @@
#include "pycore_pyerrors.h" // _PyErr_Format()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
-#include "pycore_sysmodule.h" // _PySys_GetAttr()
+#include "pycore_sysmodule.h" // _PySys_GetOptionalAttr()
#include "pycore_traceback.h" // _PyTraceBack_FromFrame()
#ifdef MS_WINDOWS
@@ -1532,14 +1532,15 @@ write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type,
PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg,
PyObject *obj)
{
- PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
+ PyObject *file;
+ if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
+ return -1;
+ }
if (file == NULL || file == Py_None) {
+ Py_XDECREF(file);
return 0;
}
- /* Hold a strong reference to ensure that sys.stderr doesn't go away
- while we use it */
- Py_INCREF(file);
int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb,
err_msg, obj, file);
Py_DECREF(file);
@@ -1638,13 +1639,20 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
goto error;
}
- PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(unraisablehook));
+ PyObject *hook;
+ if (_PySys_GetOptionalAttr(&_Py_ID(unraisablehook), &hook) < 0) {
+ Py_DECREF(hook_args);
+ err_msg_str = NULL;
+ obj = NULL;
+ goto error;
+ }
if (hook == NULL) {
Py_DECREF(hook_args);
goto default_hook;
}
if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) {
+ Py_DECREF(hook);
Py_DECREF(hook_args);
err_msg_str = "Exception ignored in audit hook";
obj = NULL;
@@ -1652,11 +1660,13 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
}
if (hook == Py_None) {
+ Py_DECREF(hook);
Py_DECREF(hook_args);
goto default_hook;
}
PyObject *res = PyObject_CallOneArg(hook, hook_args);
+ Py_DECREF(hook);
Py_DECREF(hook_args);
if (res != NULL) {
Py_DECREF(res);