mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +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
|
@ -23,7 +23,7 @@
|
|||
#include "pycore_pylifecycle.h" // _Py_FdIsInteractive()
|
||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||
#include "pycore_pythonrun.h" // export _PyRun_InteractiveLoopObject()
|
||||
#include "pycore_sysmodule.h" // _PySys_GetAttr()
|
||||
#include "pycore_sysmodule.h" // _PySys_SetAttr()
|
||||
#include "pycore_traceback.h" // _PyTraceBack_Print()
|
||||
|
||||
#include "errcode.h" // E_EOF
|
||||
|
@ -110,17 +110,35 @@ _PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flag
|
|||
flags = &local_flags;
|
||||
}
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *v = _PySys_GetAttr(tstate, &_Py_ID(ps1));
|
||||
if (v == NULL) {
|
||||
_PySys_SetAttr(&_Py_ID(ps1), v = PyUnicode_FromString(">>> "));
|
||||
Py_XDECREF(v);
|
||||
PyObject *v;
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &v) < 0) {
|
||||
PyErr_Print();
|
||||
return -1;
|
||||
}
|
||||
v = _PySys_GetAttr(tstate, &_Py_ID(ps2));
|
||||
if (v == NULL) {
|
||||
_PySys_SetAttr(&_Py_ID(ps2), v = PyUnicode_FromString("... "));
|
||||
Py_XDECREF(v);
|
||||
v = PyUnicode_FromString(">>> ");
|
||||
if (v == NULL) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (_PySys_SetAttr(&_Py_ID(ps1), v) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
Py_XDECREF(v);
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(ps2), &v) < 0) {
|
||||
PyErr_Print();
|
||||
return -1;
|
||||
}
|
||||
if (v == NULL) {
|
||||
v = PyUnicode_FromString("... ");
|
||||
if (v == NULL) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (_PySys_SetAttr(&_Py_ID(ps2), v) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
Py_XDECREF(v);
|
||||
|
||||
#ifdef Py_REF_DEBUG
|
||||
int show_ref_count = _Py_GetConfig()->show_ref_count;
|
||||
|
@ -180,31 +198,37 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename,
|
|||
PyCompilerFlags *flags, PyArena *arena,
|
||||
mod_ty *pmod, PyObject** interactive_src)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
||||
// Get sys.stdin.encoding (as UTF-8)
|
||||
PyObject *attr; // borrowed ref
|
||||
PyObject *attr;
|
||||
PyObject *encoding_obj = NULL;
|
||||
const char *encoding = NULL;
|
||||
if (fp == stdin) {
|
||||
attr = _PySys_GetAttr(tstate, &_Py_ID(stdin));
|
||||
if (attr && attr != Py_None) {
|
||||
encoding_obj = PyObject_GetAttr(attr, &_Py_ID(encoding));
|
||||
if (encoding_obj) {
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stdin), &attr) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
else if (attr != NULL && attr != Py_None) {
|
||||
if (PyObject_GetOptionalAttr(attr, &_Py_ID(encoding), &encoding_obj) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
else if (encoding_obj && PyUnicode_Check(encoding_obj)) {
|
||||
encoding = PyUnicode_AsUTF8(encoding_obj);
|
||||
if (!encoding) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Py_XDECREF(attr);
|
||||
}
|
||||
|
||||
// Get sys.ps1 (as UTF-8)
|
||||
attr = _PySys_GetAttr(tstate, &_Py_ID(ps1));
|
||||
PyObject *ps1_obj = NULL;
|
||||
const char *ps1 = "";
|
||||
if (attr != NULL) {
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &attr) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
else if (attr != NULL) {
|
||||
ps1_obj = PyObject_Str(attr);
|
||||
Py_DECREF(attr);
|
||||
if (ps1_obj == NULL) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
@ -218,11 +242,14 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename,
|
|||
}
|
||||
|
||||
// Get sys.ps2 (as UTF-8)
|
||||
attr = _PySys_GetAttr(tstate, &_Py_ID(ps2));
|
||||
PyObject *ps2_obj = NULL;
|
||||
const char *ps2 = "";
|
||||
if (attr != NULL) {
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(ps2), &attr) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
else if (attr != NULL) {
|
||||
ps2_obj = PyObject_Str(attr);
|
||||
Py_DECREF(attr);
|
||||
if (ps2_obj == NULL) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
@ -627,9 +654,11 @@ _Py_HandleSystemExitAndKeyboardInterrupt(int *exitcode_p)
|
|||
Py_SETREF(exc, code);
|
||||
}
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *sys_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
|
||||
if (sys_stderr != NULL && sys_stderr != Py_None) {
|
||||
PyObject *sys_stderr;
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &sys_stderr) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
else if (sys_stderr != NULL && sys_stderr != Py_None) {
|
||||
if (PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
@ -641,6 +670,7 @@ _Py_HandleSystemExitAndKeyboardInterrupt(int *exitcode_p)
|
|||
fflush(stderr);
|
||||
}
|
||||
PySys_WriteStderr("\n");
|
||||
Py_XDECREF(sys_stderr);
|
||||
Py_CLEAR(exc);
|
||||
*exitcode_p = 1;
|
||||
return 1;
|
||||
|
@ -660,7 +690,7 @@ handle_system_exit(void)
|
|||
static void
|
||||
_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
|
||||
{
|
||||
PyObject *typ = NULL, *tb = NULL;
|
||||
PyObject *typ = NULL, *tb = NULL, *hook = NULL;
|
||||
handle_system_exit();
|
||||
|
||||
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||
|
@ -689,7 +719,9 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
|
|||
_PyErr_Clear(tstate);
|
||||
}
|
||||
}
|
||||
PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(excepthook));
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(excepthook), &hook) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None,
|
||||
typ, exc, tb) < 0) {
|
||||
if (PyErr_ExceptionMatches(PyExc_RuntimeError)) {
|
||||
|
@ -723,6 +755,7 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
|
|||
}
|
||||
|
||||
done:
|
||||
Py_XDECREF(hook);
|
||||
Py_XDECREF(typ);
|
||||
Py_XDECREF(exc);
|
||||
Py_XDECREF(tb);
|
||||
|
@ -1160,17 +1193,24 @@ fallback:
|
|||
void
|
||||
PyErr_Display(PyObject *unused, PyObject *value, PyObject *tb)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
|
||||
PyObject *file;
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
|
||||
PyObject *exc = PyErr_GetRaisedException();
|
||||
_PyObject_Dump(value);
|
||||
fprintf(stderr, "lost sys.stderr\n");
|
||||
_PyObject_Dump(exc);
|
||||
Py_DECREF(exc);
|
||||
return;
|
||||
}
|
||||
if (file == NULL) {
|
||||
_PyObject_Dump(value);
|
||||
fprintf(stderr, "lost sys.stderr\n");
|
||||
return;
|
||||
}
|
||||
if (file == Py_None) {
|
||||
Py_DECREF(file);
|
||||
return;
|
||||
}
|
||||
Py_INCREF(file);
|
||||
_PyErr_Display(file, NULL, value, tb);
|
||||
Py_DECREF(file);
|
||||
}
|
||||
|
@ -1277,11 +1317,15 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
|
|||
static void
|
||||
flush_io_stream(PyThreadState *tstate, PyObject *name)
|
||||
{
|
||||
PyObject *f = _PySys_GetAttr(tstate, name);
|
||||
PyObject *f;
|
||||
if (_PySys_GetOptionalAttr(name, &f) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (f != NULL) {
|
||||
if (_PyFile_Flush(f) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
Py_DECREF(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue