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().
This commit is contained in:
Serhiy Storchaka 2025-02-25 23:04:27 +02:00 committed by GitHub
parent 2dad1e08ec
commit 0ef4ffeefd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 513 additions and 213 deletions

View file

@ -56,6 +56,7 @@ Revision history:
#include "Python.h"
#include "osdefs.h" // SEP
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
#include <syslog.h>
@ -89,45 +90,50 @@ syslog_get_argv(void)
Py_ssize_t argv_len, scriptlen;
PyObject *scriptobj;
Py_ssize_t slash;
PyObject *argv = PySys_GetObject("argv");
PyObject *argv;
if (argv == NULL) {
return(NULL);
if (_PySys_GetOptionalAttrString("argv", &argv) <= 0) {
return NULL;
}
argv_len = PyList_Size(argv);
if (argv_len == -1) {
PyErr_Clear();
return(NULL);
Py_DECREF(argv);
return NULL;
}
if (argv_len == 0) {
return(NULL);
Py_DECREF(argv);
return NULL;
}
scriptobj = PyList_GetItem(argv, 0);
Py_XINCREF(scriptobj);
Py_DECREF(argv);
if (scriptobj == NULL) {
PyErr_Clear();
return NULL;
}
if (!PyUnicode_Check(scriptobj)) {
return(NULL);
Py_DECREF(scriptobj);
return NULL;
}
scriptlen = PyUnicode_GET_LENGTH(scriptobj);
if (scriptlen == 0) {
return(NULL);
Py_DECREF(scriptobj);
return NULL;
}
slash = PyUnicode_FindChar(scriptobj, SEP, 0, scriptlen, -1);
if (slash == -2) {
PyErr_Clear();
Py_DECREF(scriptobj);
return NULL;
}
if (slash != -1) {
return PyUnicode_Substring(scriptobj, slash + 1, scriptlen);
} else {
Py_INCREF(scriptobj);
return(scriptobj);
Py_SETREF(scriptobj, PyUnicode_Substring(scriptobj, slash + 1, scriptlen));
}
return scriptobj;
}
@ -162,6 +168,9 @@ syslog_openlog_impl(PyObject *module, PyObject *ident, long logopt,
else {
/* get sys.argv[0] or NULL if we can't for some reason */
ident = syslog_get_argv();
if (ident == NULL && PyErr_Occurred()) {
return NULL;
}
}
/* At this point, ident should be INCREF()ed. openlog(3) does not