[Python-checkins] commit of r41845 - in python/trunk: Lib/test/test_descr.py Objects/typeobject.c
armin.rigo
python-checkins at python.org
Thu Dec 29 18:07:41 CET 2005
Author: armin.rigo
Date: Thu Dec 29 18:07:39 2005
New Revision: 41845
Modified:
python/trunk/Lib/test/test_descr.py
python/trunk/Objects/typeobject.c
Log:
SF bug #1153075: "PyXxx_Check(x) trusts x->ob_type->tp_mro".
A patch by mwh to check that user-defined mro's are reasonable
enough.
Modified: python/trunk/Lib/test/test_descr.py
==============================================================================
--- python/trunk/Lib/test/test_descr.py (original)
+++ python/trunk/Lib/test/test_descr.py Thu Dec 29 18:07:39 2005
@@ -1635,6 +1635,37 @@
vereq(X.__mro__, (object, A, C, B, D, X))
vereq(X().f(), "A")
+ try:
+ class X(object):
+ class __metaclass__(type):
+ def mro(self):
+ return [self, dict, object]
+ except TypeError:
+ pass
+ else:
+ raise TestFailed, "devious mro() return not caught"
+
+ try:
+ class X(object):
+ class __metaclass__(type):
+ def mro(self):
+ return [1]
+ except TypeError:
+ pass
+ else:
+ raise TestFailed, "non-class mro() return not caught"
+
+ try:
+ class X(object):
+ class __metaclass__(type):
+ def mro(self):
+ return 1
+ except TypeError:
+ pass
+ else:
+ raise TestFailed, "non-sequence mro() return not caught"
+
+
def overloading():
if verbose: print "Testing operator overloading..."
Modified: python/trunk/Objects/typeobject.c
==============================================================================
--- python/trunk/Objects/typeobject.c (original)
+++ python/trunk/Objects/typeobject.c Thu Dec 29 18:07:39 2005
@@ -1288,12 +1288,14 @@
mro_internal(PyTypeObject *type)
{
PyObject *mro, *result, *tuple;
+ int checkit = 0;
if (type->ob_type == &PyType_Type) {
result = mro_implementation(type);
}
else {
static PyObject *mro_str;
+ checkit = 1;
mro = lookup_method((PyObject *)type, "mro", &mro_str);
if (mro == NULL)
return -1;
@@ -1304,6 +1306,37 @@
return -1;
tuple = PySequence_Tuple(result);
Py_DECREF(result);
+ if (tuple == NULL)
+ return -1;
+ if (checkit) {
+ int i, len;
+ PyObject *cls;
+ PyTypeObject *solid;
+
+ solid = solid_base(type);
+
+ len = PyTuple_GET_SIZE(tuple);
+
+ for (i = 0; i < len; i++) {
+ PyTypeObject *t;
+ cls = PyTuple_GET_ITEM(tuple, i);
+ if (PyClass_Check(cls))
+ continue;
+ else if (!PyType_Check(cls)) {
+ PyErr_Format(PyExc_TypeError,
+ "mro() returned a non-class ('%.500s')",
+ cls->ob_type->tp_name);
+ return -1;
+ }
+ t = (PyTypeObject*)cls;
+ if (!PyType_IsSubtype(solid, solid_base(t))) {
+ PyErr_Format(PyExc_TypeError,
+ "mro() returned base with unsuitable layout ('%.500s')",
+ t->tp_name);
+ return -1;
+ }
+ }
+ }
type->tp_mro = tuple;
return 0;
}
More information about the Python-checkins
mailing list