Fixed SOE in PyClass.isOverriddenMRO() check (PY-15002)

In Python 2 it is possible to create an endless metaclass chain by
defining '__metaclass__' at the top-level to be one of the classes
defined in the module. We assume that these circular metaclasses don't
override `mro()` in order to prevent infinite recursion in this check.
This commit is contained in:
Andrey Vlasovskikh
2015-02-17 16:46:35 +03:00
parent a57ca84020
commit 332709f9ee
3 changed files with 19 additions and 0 deletions
@@ -1359,6 +1359,9 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
final PyType metaClassType = cls.getMetaClassType(context);
if (metaClassType instanceof PyClassType) {
final PyClass metaClass = ((PyClassType)metaClassType).getPyClass();
if (cls == metaClass) {
return false;
}
final PyFunction mroMethod = metaClass.findMethodByName(PyNames.MRO, true);
if (mroMethod != null) {
final PyClass mroClass = mroMethod.getContainingClass();
@@ -0,0 +1,11 @@
class __metaclass__(object):
pass
class C(object):
def foo(self):
pass
c = C()
c.foo()
@@ -460,6 +460,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
doTest();
}
// PY-15002
public void testIncorrectFileLevelMetaclass() {
doTest();
}
@NotNull
@Override
protected Class<? extends PyInspection> getInspectionClass() {