]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-35444: Fix error handling when fail to look up builtin "getattr". (GH-11047)...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 11 Dec 2018 10:13:14 +0000 (02:13 -0800)
committerSerhiy Storchaka <storchaka@gmail.com>
Tue, 11 Dec 2018 10:13:14 +0000 (12:13 +0200)
(cherry picked from commit bb86bf4c4eaa30b1f5192dab9f389ce0bb61114d)
(cherry picked from commit 3cae16d2e98ffaa89ddd311df70a857dfaff4020)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Include/ceval.h
Misc/NEWS.d/next/Core and Builtins/2018-12-09-13-09-39.bpo-35444.9kYn4V.rst [new file with mode: 0644]
Modules/_pickle.c
Objects/classobject.c
Objects/descrobject.c
Objects/methodobject.c
Python/ceval.c

index 38d470999f73503f002c136a6decb6536387a49d..f46aef18043f7886d3f5d9ab45eace84292942d0 100644 (file)
@@ -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 (file)
index 0000000..22c3969
--- /dev/null
@@ -0,0 +1,2 @@
+Fixed error handling in pickling methods when fail to look up builtin
+"getattr".
index 8c8163560f1188dee7a857a65b6b26b854fac494..41b8fa7b3c2902a1bc348ec636185a0567ce3be7 100644 (file)
@@ -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)
index b0ed02305695da2bf2754e7defadd4a71b1ce5d9..7071016d06b9dda6fcedc53a7b0c4b68ddfec0da 100644 (file)
@@ -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[] = {
index 9d258cf111d1662d145108f4429600bd5d0d1302..e897b10926164a0aa708f82656cd5cfcfce92298 100644 (file)
@@ -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[] = {
index fe52545667f2edf81b5338a84a1cfc2041a77a27..6794bf21d9977e3d453d8d998333e3934adaa688 100644 (file)
@@ -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[] = {
index 36e966470dba54841b8cfe7877b5dfd6f9acfbc1..0b30cc1d48d181cd836c4eab5b6842aee1dba4f7 100644 (file)
@@ -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)
 {