bpo-35444: Fix error handling when fail to look up builtin "getattr". (GH-11047) (GH-11107)

(cherry picked from commit bb86bf4c4e)
This commit is contained in:
Serhiy Storchaka 2018-12-11 10:51:27 +02:00 committed by GitHub
parent 62674f3a36
commit 3cae16d2e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 29 additions and 30 deletions

View file

@ -48,10 +48,12 @@ PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void);
PyAPI_FUNC(PyObject *) PyEval_GetLocals(void);
PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void);
#ifndef Py_LIMITED_API
/* Helper to look up a builtin object */
PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *);
/* Look at the current frame's (if any) code's co_flags, and turn on
the corresponding compiler flags in cf->cf_flags. Return 1 if any
flag was set, else return 0. */
#ifndef Py_LIMITED_API
PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);
#endif

View file

@ -0,0 +1,2 @@
Fixed error handling in pickling methods when fail to look up builtin
"getattr".

View file

@ -207,19 +207,15 @@ _Pickle_ClearState(PickleState *st)
static int
_Pickle_InitState(PickleState *st)
{
PyObject *builtins;
PyObject *copyreg = NULL;
PyObject *compat_pickle = NULL;
PyObject *codecs = NULL;
PyObject *functools = NULL;
_Py_IDENTIFIER(getattr);
builtins = PyEval_GetBuiltins();
if (builtins == NULL)
goto error;
st->getattr = PyDict_GetItemString(builtins, "getattr");
st->getattr = _PyEval_GetBuiltinId(&PyId_getattr);
if (st->getattr == NULL)
goto error;
Py_INCREF(st->getattr);
copyreg = PyImport_ImportModule("copyreg");
if (!copyreg)

View file

@ -77,8 +77,6 @@ method_reduce(PyMethodObject *im)
{
PyObject *self = PyMethod_GET_SELF(im);
PyObject *func = PyMethod_GET_FUNCTION(im);
PyObject *builtins;
PyObject *getattr;
PyObject *funcname;
_Py_IDENTIFIER(getattr);
@ -86,9 +84,8 @@ method_reduce(PyMethodObject *im)
if (funcname == NULL) {
return NULL;
}
builtins = PyEval_GetBuiltins();
getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
return Py_BuildValue("O(ON)", getattr, self, funcname);
return Py_BuildValue("N(ON)", _PyEval_GetBuiltinId(&PyId_getattr),
self, funcname);
}
static PyMethodDef method_methods[] = {

View file

@ -450,14 +450,9 @@ descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
static PyObject *
descr_reduce(PyDescrObject *descr)
{
PyObject *builtins;
PyObject *getattr;
_Py_IDENTIFIER(getattr);
builtins = PyEval_GetBuiltins();
getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
return Py_BuildValue("O(OO)", getattr, PyDescr_TYPE(descr),
PyDescr_NAME(descr));
return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
PyDescr_TYPE(descr), PyDescr_NAME(descr));
}
static PyMethodDef descr_methods[] = {
@ -1088,13 +1083,9 @@ wrapper_repr(wrapperobject *wp)
static PyObject *
wrapper_reduce(wrapperobject *wp)
{
PyObject *builtins;
PyObject *getattr;
_Py_IDENTIFIER(getattr);
builtins = PyEval_GetBuiltins();
getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
return Py_BuildValue("O(OO)", getattr, wp->self, PyDescr_NAME(wp->descr));
return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
wp->self, PyDescr_NAME(wp->descr));
}
static PyMethodDef wrapper_methods[] = {

View file

@ -103,16 +103,13 @@ meth_dealloc(PyCFunctionObject *m)
static PyObject *
meth_reduce(PyCFunctionObject *m)
{
PyObject *builtins;
PyObject *getattr;
_Py_IDENTIFIER(getattr);
if (m->m_self == NULL || PyModule_Check(m->m_self))
return PyUnicode_FromString(m->m_ml->ml_name);
builtins = PyEval_GetBuiltins();
getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
return Py_BuildValue("O(Os)", getattr, m->m_self, m->m_ml->ml_name);
return Py_BuildValue("N(Os)", _PyEval_GetBuiltinId(&PyId_getattr),
m->m_self, m->m_ml->ml_name);
}
static PyMethodDef meth_methods[] = {

View file

@ -4419,6 +4419,20 @@ PyEval_GetBuiltins(void)
return current_frame->f_builtins;
}
/* Convenience function to get a builtin from its name */
PyObject *
_PyEval_GetBuiltinId(_Py_Identifier *name)
{
PyObject *attr = _PyDict_GetItemIdWithError(PyEval_GetBuiltins(), name);
if (attr) {
Py_INCREF(attr);
}
else if (!PyErr_Occurred()) {
PyErr_SetObject(PyExc_AttributeError, _PyUnicode_FromId(name));
}
return attr;
}
PyObject *
PyEval_GetLocals(void)
{