mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
d3a1de2270
commit
a278313518
|
@ -38,7 +38,7 @@ all_name_chars(PyObject *o)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
intern_strings(PyObject *tuple)
|
intern_strings(PyObject *tuple)
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
@ -46,60 +46,70 @@ intern_strings(PyObject *tuple)
|
||||||
for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
|
for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
|
||||||
PyObject *v = PyTuple_GET_ITEM(tuple, i);
|
PyObject *v = PyTuple_GET_ITEM(tuple, i);
|
||||||
if (v == NULL || !PyUnicode_CheckExact(v)) {
|
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]);
|
PyUnicode_InternInPlace(&_PyTuple_ITEMS(tuple)[i]);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Intern selected string constants */
|
/* Intern selected string constants */
|
||||||
static int
|
static int
|
||||||
intern_string_constants(PyObject *tuple)
|
intern_string_constants(PyObject *tuple, int *modified)
|
||||||
{
|
{
|
||||||
int modified = 0;
|
for (Py_ssize_t i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
|
||||||
Py_ssize_t i;
|
|
||||||
|
|
||||||
for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
|
|
||||||
PyObject *v = PyTuple_GET_ITEM(tuple, i);
|
PyObject *v = PyTuple_GET_ITEM(tuple, i);
|
||||||
if (PyUnicode_CheckExact(v)) {
|
if (PyUnicode_CheckExact(v)) {
|
||||||
if (PyUnicode_READY(v) == -1) {
|
if (PyUnicode_READY(v) == -1) {
|
||||||
PyErr_Clear();
|
return -1;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (all_name_chars(v)) {
|
if (all_name_chars(v)) {
|
||||||
PyObject *w = v;
|
PyObject *w = v;
|
||||||
PyUnicode_InternInPlace(&v);
|
PyUnicode_InternInPlace(&v);
|
||||||
if (w != v) {
|
if (w != v) {
|
||||||
PyTuple_SET_ITEM(tuple, i, v);
|
PyTuple_SET_ITEM(tuple, i, v);
|
||||||
modified = 1;
|
if (modified) {
|
||||||
|
*modified = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (PyTuple_CheckExact(v)) {
|
else if (PyTuple_CheckExact(v)) {
|
||||||
intern_string_constants(v);
|
if (intern_string_constants(v, NULL) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (PyFrozenSet_CheckExact(v)) {
|
else if (PyFrozenSet_CheckExact(v)) {
|
||||||
PyObject *w = v;
|
PyObject *w = v;
|
||||||
PyObject *tmp = PySequence_Tuple(v);
|
PyObject *tmp = PySequence_Tuple(v);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
PyErr_Clear();
|
return -1;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
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);
|
v = PyFrozenSet_New(tmp);
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
PyErr_Clear();
|
Py_DECREF(tmp);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
PyTuple_SET_ITEM(tuple, i, v);
|
PyTuple_SET_ITEM(tuple, i, v);
|
||||||
Py_DECREF(w);
|
Py_DECREF(w);
|
||||||
modified = 1;
|
if (modified) {
|
||||||
|
*modified = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_DECREF(tmp);
|
Py_DECREF(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return modified;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyCodeObject *
|
PyCodeObject *
|
||||||
|
@ -139,11 +149,21 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
intern_strings(names);
|
if (intern_strings(names) < 0) {
|
||||||
intern_strings(varnames);
|
return NULL;
|
||||||
intern_strings(freevars);
|
}
|
||||||
intern_strings(cellvars);
|
if (intern_strings(varnames) < 0) {
|
||||||
intern_string_constants(consts);
|
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 */
|
/* Check for any inner or outer closure references */
|
||||||
n_cellvars = PyTuple_GET_SIZE(cellvars);
|
n_cellvars = PyTuple_GET_SIZE(cellvars);
|
||||||
|
|
Loading…
Reference in New Issue