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

@ -3470,10 +3470,13 @@ _Py_DumpPathConfig(PyThreadState *tstate)
#define DUMP_SYS(NAME) \
do { \
obj = PySys_GetObject(#NAME); \
PySys_FormatStderr(" sys.%s = ", #NAME); \
if (_PySys_GetOptionalAttrString(#NAME, &obj) < 0) { \
PyErr_Clear(); \
} \
if (obj != NULL) { \
PySys_FormatStderr("%A", obj); \
Py_DECREF(obj); \
} \
else { \
PySys_WriteStderr("(not set)"); \
@ -3491,7 +3494,8 @@ _Py_DumpPathConfig(PyThreadState *tstate)
DUMP_SYS(exec_prefix);
#undef DUMP_SYS
PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */
PyObject *sys_path;
(void) _PySys_GetOptionalAttrString("path", &sys_path);
if (sys_path != NULL && PyList_Check(sys_path)) {
PySys_WriteStderr(" sys.path = [\n");
Py_ssize_t len = PyList_GET_SIZE(sys_path);
@ -3501,6 +3505,7 @@ _Py_DumpPathConfig(PyThreadState *tstate)
}
PySys_WriteStderr(" ]\n");
}
Py_XDECREF(sys_path);
_PyErr_SetRaisedException(tstate, exc);
}
@ -4110,22 +4115,10 @@ _PyConfig_CreateXOptionsDict(const PyConfig *config)
}
static PyObject*
config_get_sys(const char *name)
{
PyObject *value = PySys_GetObject(name);
if (value == NULL) {
PyErr_Format(PyExc_RuntimeError, "lost sys.%s", name);
return NULL;
}
return Py_NewRef(value);
}
static int
config_get_sys_write_bytecode(const PyConfig *config, int *value)
{
PyObject *attr = config_get_sys("dont_write_bytecode");
PyObject *attr = _PySys_GetRequiredAttrString("dont_write_bytecode");
if (attr == NULL) {
return -1;
}
@ -4146,7 +4139,7 @@ config_get(const PyConfig *config, const PyConfigSpec *spec,
{
if (use_sys) {
if (spec->sys.attr != NULL) {
return config_get_sys(spec->sys.attr);
return _PySys_GetRequiredAttrString(spec->sys.attr);
}
if (strcmp(spec->name, "write_bytecode") == 0) {