diff options
| author | Serhiy Storchaka <storchaka@gmail.com> | 2025-02-26 15:20:47 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-26 15:20:47 (GMT) |
| commit | 89a79fc919419bfe817da13bc2a4437908d7fc07 (patch) | |
| tree | d8ca3bac7229ea443ff9d591b0459caac0b67cb1 /Python/pythonrun.c | |
| parent | 6a268a046f474e860c8d0186a859fdd075d80463 (diff) | |
| download | cpython-89a79fc919419bfe817da13bc2a4437908d7fc07.zip cpython-89a79fc919419bfe817da13bc2a4437908d7fc07.tar.gz cpython-89a79fc919419bfe817da13bc2a4437908d7fc07.tar.bz2 | |
[3.12] gh-130163: Fix crashes related to PySys_GetObject() (GH-130503) (GH-130556) (GH-130576)
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().
(cherry picked from commit 0ef4ffeefd1737c18dc9326133c7894d58108c2e)
(cherry picked from commit 7c1b76fce8c8df00da38830f72dbdde6881a33be)
(cherry picked from commit 2ab7e1135a2d5ca45b60881ece27729e4fc0ee8b)
Diffstat (limited to 'Python/pythonrun.c')
| -rw-r--r-- | Python/pythonrun.c | 83 |
1 files changed, 62 insertions, 21 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index cf84573..ac71e73 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -115,17 +115,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; @@ -190,11 +208,12 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, PyArena *arena; const char *ps1 = "", *ps2 = "", *enc = NULL; int errcode = 0; - PyThreadState *tstate = _PyThreadState_GET(); if (fp == stdin) { /* Fetch encoding from sys.stdin if possible. */ - v = _PySys_GetAttr(tstate, &_Py_ID(stdin)); + if (_PySys_GetOptionalAttr(&_Py_ID(stdin), &v) < 0) { + return -1; + } if (v && v != Py_None) { oenc = PyObject_GetAttr(v, &_Py_ID(encoding)); if (oenc) @@ -202,10 +221,14 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, if (!enc) PyErr_Clear(); } + Py_XDECREF(v); + } + if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &v) < 0) { + Py_XDECREF(oenc); + return -1; } - v = _PySys_GetAttr(tstate, &_Py_ID(ps1)); if (v != NULL) { - v = PyObject_Str(v); + Py_SETREF(v, PyObject_Str(v)); if (v == NULL) PyErr_Clear(); else if (PyUnicode_Check(v)) { @@ -216,9 +239,12 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, } } } - w = _PySys_GetAttr(tstate, &_Py_ID(ps2)); + if (_PySys_GetOptionalAttr(&_Py_ID(ps2), &w) < 0) { + Py_XDECREF(oenc); + return -1; + } if (w != NULL) { - w = PyObject_Str(w); + Py_SETREF(w, PyObject_Str(w)); if (w == NULL) PyErr_Clear(); else if (PyUnicode_Check(w)) { @@ -718,8 +744,8 @@ _Py_HandleSystemExit(int *exitcode_p) exitcode = (int)PyLong_AsLong(exc); } else { - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *sys_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); + PyObject *sys_stderr; + (void) _PySys_GetOptionalAttr(&_Py_ID(stderr), &sys_stderr); /* We clear the exception here to avoid triggering the assertion * in PyObject_Str that ensures it won't silently lose exception * details. @@ -731,6 +757,7 @@ _Py_HandleSystemExit(int *exitcode_p) PyObject_Print(exc, stderr, Py_PRINT_RAW); fflush(stderr); } + Py_XDECREF(sys_stderr); PySys_WriteStderr("\n"); exitcode = 1; } @@ -755,7 +782,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); @@ -784,7 +811,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)) { @@ -821,6 +850,7 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) } done: + Py_XDECREF(hook); Py_XDECREF(typ); Py_XDECREF(exc); Py_XDECREF(tb); @@ -1567,17 +1597,24 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb) 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); } @@ -1664,7 +1701,10 @@ 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) { PyObject *r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); if (r) { @@ -1673,6 +1713,7 @@ flush_io_stream(PyThreadState *tstate, PyObject *name) else { PyErr_Clear(); } + Py_DECREF(f); } } |
