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

@ -31,6 +31,7 @@ Copyright (C) 1994 Steen Lumholt.
#endif
#include "pycore_long.h" // _PyLong_IsNegative()
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
#ifdef MS_WINDOWS
# include <windows.h>
@ -142,8 +143,9 @@ _get_tcl_lib_path(void)
if (already_checked == 0) {
struct stat stat_buf;
int stat_return_value;
PyObject *prefix;
PyObject *prefix = PySys_GetObject("base_prefix"); // borrowed reference
(void) _PySys_GetOptionalAttrString("base_prefix", &prefix);
if (prefix == NULL) {
return NULL;
}
@ -151,9 +153,11 @@ _get_tcl_lib_path(void)
/* Check expected location for an installed Python first */
tcl_library_path = PyUnicode_FromString("\\tcl\\tcl" TCL_VERSION);
if (tcl_library_path == NULL) {
Py_DECREF(prefix);
return NULL;
}
tcl_library_path = PyUnicode_Concat(prefix, tcl_library_path);
Py_DECREF(prefix);
if (tcl_library_path == NULL) {
return NULL;
}
@ -3516,9 +3520,10 @@ PyInit__tkinter(void)
/* This helps the dynamic loader; in Unicode aware Tcl versions
it also helps Tcl find its encodings. */
uexe = PySys_GetObject("executable"); // borrowed reference
(void) _PySys_GetOptionalAttrString("executable", &uexe);
if (uexe && PyUnicode_Check(uexe)) { // sys.executable can be None
cexe = PyUnicode_EncodeFSDefault(uexe);
Py_DECREF(uexe);
if (cexe) {
#ifdef MS_WINDOWS
int set_var = 0;
@ -3531,12 +3536,14 @@ PyInit__tkinter(void)
if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
str_path = _get_tcl_lib_path();
if (str_path == NULL && PyErr_Occurred()) {
Py_DECREF(cexe);
Py_DECREF(m);
return NULL;
}
if (str_path != NULL) {
wcs_path = PyUnicode_AsWideCharString(str_path, NULL);
if (wcs_path == NULL) {
Py_DECREF(cexe);
Py_DECREF(m);
return NULL;
}
@ -3557,6 +3564,9 @@ PyInit__tkinter(void)
}
Py_XDECREF(cexe);
}
else {
Py_XDECREF(uexe);
}
if (PyErr_Occurred()) {
Py_DECREF(m);