summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2018-12-11 10:13:14 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2018-12-11 10:13:14 (GMT)
commitbe6ec444729f727f304ae10f3a7e2feda3cc3aaa (patch)
treee6f2d90acb8b9e9b6d9903e809656209b36e82df
parentf74cabd9203cf3be97fdb3821a7fa0b74d7b2263 (diff)
downloadcpython-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.h4
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2018-12-09-13-09-39.bpo-35444.9kYn4V.rst2
-rw-r--r--Modules/_pickle.c8
-rw-r--r--Objects/classobject.c7
-rw-r--r--Objects/descrobject.c17
-rw-r--r--Objects/methodobject.c7
-rw-r--r--Python/ceval.c14
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)
{