mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
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:
parent
2dad1e08ec
commit
0ef4ffeefd
23 changed files with 513 additions and 213 deletions
|
@ -27,7 +27,7 @@
|
|||
#include "pycore_runtime_init.h" // _PyRuntimeState_INIT
|
||||
#include "pycore_setobject.h" // _PySet_NextEntry()
|
||||
#include "pycore_sliceobject.h" // _PySlice_Fini()
|
||||
#include "pycore_sysmodule.h" // _PySys_GetAttr()
|
||||
#include "pycore_sysmodule.h" // _PySys_ClearAttrString()
|
||||
#include "pycore_traceback.h" // _Py_DumpTracebackThreads()
|
||||
#include "pycore_uniqueid.h" // _PyObject_FinalizeUniqueIdPool()
|
||||
#include "pycore_typeobject.h" // _PyTypes_InitTypes()
|
||||
|
@ -1254,8 +1254,12 @@ init_interp_main(PyThreadState *tstate)
|
|||
|
||||
if (is_main_interp) {
|
||||
/* Initialize warnings. */
|
||||
PyObject *warnoptions = PySys_GetObject("warnoptions");
|
||||
if (warnoptions != NULL && PyList_Size(warnoptions) > 0)
|
||||
PyObject *warnoptions;
|
||||
if (_PySys_GetOptionalAttrString("warnoptions", &warnoptions) < 0) {
|
||||
return _PyStatus_ERR("can't initialize warnings");
|
||||
}
|
||||
if (warnoptions != NULL && PyList_Check(warnoptions) &&
|
||||
PyList_Size(warnoptions) > 0)
|
||||
{
|
||||
PyObject *warnings_module = PyImport_ImportModule("warnings");
|
||||
if (warnings_module == NULL) {
|
||||
|
@ -1264,6 +1268,7 @@ init_interp_main(PyThreadState *tstate)
|
|||
}
|
||||
Py_XDECREF(warnings_module);
|
||||
}
|
||||
Py_XDECREF(warnoptions);
|
||||
|
||||
interp->runtime->initialized = 1;
|
||||
}
|
||||
|
@ -1770,24 +1775,33 @@ file_is_closed(PyObject *fobj)
|
|||
static int
|
||||
flush_std_files(void)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *fout = _PySys_GetAttr(tstate, &_Py_ID(stdout));
|
||||
PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
|
||||
PyObject *file;
|
||||
int status = 0;
|
||||
|
||||
if (fout != NULL && fout != Py_None && !file_is_closed(fout)) {
|
||||
if (_PyFile_Flush(fout) < 0) {
|
||||
PyErr_FormatUnraisable("Exception ignored while flushing sys.stdout");
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stdout), &file) < 0) {
|
||||
status = -1;
|
||||
}
|
||||
else if (file != NULL && file != Py_None && !file_is_closed(file)) {
|
||||
if (_PyFile_Flush(file) < 0) {
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
if (status < 0) {
|
||||
PyErr_FormatUnraisable("Exception ignored while flushing sys.stdout");
|
||||
}
|
||||
Py_XDECREF(file);
|
||||
|
||||
if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) {
|
||||
if (_PyFile_Flush(ferr) < 0) {
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
|
||||
PyErr_Clear();
|
||||
status = -1;
|
||||
}
|
||||
else if (file != NULL && file != Py_None && !file_is_closed(file)) {
|
||||
if (_PyFile_Flush(file) < 0) {
|
||||
PyErr_Clear();
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
Py_XDECREF(file);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -2998,10 +3012,14 @@ _Py_FatalError_PrintExc(PyThreadState *tstate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
|
||||
PyObject *ferr;
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &ferr) < 0) {
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
if (ferr == NULL || ferr == Py_None) {
|
||||
/* sys.stderr is not set yet or set to None,
|
||||
no need to try to display the exception */
|
||||
Py_XDECREF(ferr);
|
||||
Py_DECREF(exc);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3017,6 +3035,7 @@ _Py_FatalError_PrintExc(PyThreadState *tstate)
|
|||
if (_PyFile_Flush(ferr) < 0) {
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
Py_DECREF(ferr);
|
||||
|
||||
return has_tb;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue