From a27831351873bd7eff10863353d475c29fb0d7bb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 27 Jan 2020 23:24:13 +0100 Subject: bpo-38631: Avoid Py_FatalError() in PyCode_New() (GH-18215) intern_strings() now raises a SystemError, rather than calling Py_FatalError(). intern_string_constants() now reports exceptions to the caller, rather than ignoring silently exceptions. --- Objects/codeobject.c | 72 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 522e1a9..c6759c9 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -38,7 +38,7 @@ all_name_chars(PyObject *o) return 1; } -static void +static int intern_strings(PyObject *tuple) { Py_ssize_t i; @@ -46,60 +46,70 @@ intern_strings(PyObject *tuple) for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { PyObject *v = PyTuple_GET_ITEM(tuple, i); if (v == NULL || !PyUnicode_CheckExact(v)) { - Py_FatalError("non-string found in code slot"); + PyErr_SetString(PyExc_SystemError, + "non-string found in code slot"); + return -1; } PyUnicode_InternInPlace(&_PyTuple_ITEMS(tuple)[i]); } + return 0; } /* Intern selected string constants */ static int -intern_string_constants(PyObject *tuple) +intern_string_constants(PyObject *tuple, int *modified) { - int modified = 0; - Py_ssize_t i; - - for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { + for (Py_ssize_t i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { PyObject *v = PyTuple_GET_ITEM(tuple, i); if (PyUnicode_CheckExact(v)) { if (PyUnicode_READY(v) == -1) { - PyErr_Clear(); - continue; + return -1; } + if (all_name_chars(v)) { PyObject *w = v; PyUnicode_InternInPlace(&v); if (w != v) { PyTuple_SET_ITEM(tuple, i, v); - modified = 1; + if (modified) { + *modified = 1; + } } } } else if (PyTuple_CheckExact(v)) { - intern_string_constants(v); + if (intern_string_constants(v, NULL) < 0) { + return -1; + } } else if (PyFrozenSet_CheckExact(v)) { PyObject *w = v; PyObject *tmp = PySequence_Tuple(v); if (tmp == NULL) { - PyErr_Clear(); - continue; + return -1; } - if (intern_string_constants(tmp)) { + int tmp_modified = 0; + if (intern_string_constants(tmp, &tmp_modified) < 0) { + Py_DECREF(tmp); + return -1; + } + if (tmp_modified) { v = PyFrozenSet_New(tmp); if (v == NULL) { - PyErr_Clear(); + Py_DECREF(tmp); + return -1; } - else { - PyTuple_SET_ITEM(tuple, i, v); - Py_DECREF(w); - modified = 1; + + PyTuple_SET_ITEM(tuple, i, v); + Py_DECREF(w); + if (modified) { + *modified = 1; } } Py_DECREF(tmp); } } - return modified; + return 0; } PyCodeObject * @@ -139,11 +149,21 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, return NULL; } - intern_strings(names); - intern_strings(varnames); - intern_strings(freevars); - intern_strings(cellvars); - intern_string_constants(consts); + if (intern_strings(names) < 0) { + return NULL; + } + if (intern_strings(varnames) < 0) { + return NULL; + } + if (intern_strings(freevars) < 0) { + return NULL; + } + if (intern_strings(cellvars) < 0) { + return NULL; + } + if (intern_string_constants(consts, NULL) < 0) { + return NULL; + } /* Check for any inner or outer closure references */ n_cellvars = PyTuple_GET_SIZE(cellvars); @@ -513,7 +533,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) ourvarnames, ourfreevars, ourcellvars, filename, name, firstlineno, lnotab); - cleanup: + cleanup: Py_XDECREF(ournames); Py_XDECREF(ourvarnames); Py_XDECREF(ourfreevars); -- cgit v0.12