diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2018-12-11 10:13:14 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2018-12-11 10:13:14 (GMT) |
commit | be6ec444729f727f304ae10f3a7e2feda3cc3aaa (patch) | |
tree | e6f2d90acb8b9e9b6d9903e809656209b36e82df | |
parent | f74cabd9203cf3be97fdb3821a7fa0b74d7b2263 (diff) | |
download | cpython-be6ec444729f727f304ae10f3a7e2feda3cc3aaa.zip cpython-be6ec444729f727f304ae10f3a7e2feda3cc3aaa.tar.gz cpython-be6ec444729f727f304ae10f3a7e2feda3cc3aaa.tar.bz2 |
bpo-35444: Fix error handling when fail to look up builtin "getattr". (GH-11047) (GH-11107) (GH-11108)
(cherry picked from commit bb86bf4c4eaa30b1f5192dab9f389ce0bb61114d)
(cherry picked from commit 3cae16d2e98ffaa89ddd311df70a857dfaff4020)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
-rw-r--r-- | Include/ceval.h | 4 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2018-12-09-13-09-39.bpo-35444.9kYn4V.rst | 2 | ||||
-rw-r--r-- | Modules/_pickle.c | 8 | ||||
-rw-r--r-- | Objects/classobject.c | 7 | ||||
-rw-r--r-- | Objects/descrobject.c | 17 | ||||
-rw-r--r-- | Objects/methodobject.c | 7 | ||||
-rw-r--r-- | Python/ceval.c | 14 |
7 files changed, 29 insertions, 30 deletions
diff --git a/Include/ceval.h b/Include/ceval.h index 38d4709..f46aef1 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -38,10 +38,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 diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-12-09-13-09-39.bpo-35444.9kYn4V.rst b/Misc/NEWS.d/next/Core and Builtins/2018-12-09-13-09-39.bpo-35444.9kYn4V.rst new file mode 100644 index 0000000..22c3969 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-12-09-13-09-39.bpo-35444.9kYn4V.rst @@ -0,0 +1,2 @@ +Fixed error handling in pickling methods when fail to look up builtin +"getattr". diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 8c81635..41b8fa7 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -200,19 +200,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) diff --git a/Objects/classobject.c b/Objects/classobject.c index b0ed023..7071016 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -75,8 +75,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); @@ -84,9 +82,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[] = { diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 9d258cf..e897b10 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -389,14 +389,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[] = { @@ -1098,13 +1093,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[] = { diff --git a/Objects/methodobject.c b/Objects/methodobject.c index fe52545..6794bf2 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -320,16 +320,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[] = { diff --git a/Python/ceval.c b/Python/ceval.c index 36e9664..0b30cc1 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4667,6 +4667,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) { |