diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2025-02-25 21:04:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-25 21:04:27 (GMT) |
commit | 0ef4ffeefd1737c18dc9326133c7894d58108c2e (patch) | |
tree | dc3614077d06e68df192e57505951b80012a2e31 /Python/pythonrun.c | |
parent | 2dad1e08ec9d5ddc798a313900613b3d1eeaff6b (diff) | |
download | cpython-0ef4ffeefd1737c18dc9326133c7894d58108c2e.zip cpython-0ef4ffeefd1737c18dc9326133c7894d58108c2e.tar.gz cpython-0ef4ffeefd1737c18dc9326133c7894d58108c2e.tar.bz2 |
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().
Diffstat (limited to 'Python/pythonrun.c')
-rw-r--r-- | Python/pythonrun.c | 100 |
1 files changed, 72 insertions, 28 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 36390da..9b882d9 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -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)); + PyObject *v; + if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &v) < 0) { + PyErr_Print(); + return -1; + } if (v == NULL) { - _PySys_SetAttr(&_Py_ID(ps1), 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; } - 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(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); } } |