protect against SOE when iterating superclasses (PY-846)

This commit is contained in:
Dmitry Jemerov
2010-04-16 16:04:15 +04:00
parent 32c33bfda7
commit 4849d7e4b0
5 changed files with 29 additions and 6 deletions
@@ -529,8 +529,8 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
}
private static class AncestorsIterator implements Iterator<PyClass> {
List<PyClass> pending = new LinkedList<PyClass>();
Set<PyClass> seen = new HashSet<PyClass>();
List<PyClassImpl> pending = new LinkedList<PyClassImpl>();
Set<PyClass> seen;
Iterator<PyClass> percolator;
PyClass prefetch = null;
private final PyClassImpl myAClass;
@@ -538,6 +538,13 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
public AncestorsIterator(PyClassImpl aClass) {
myAClass = aClass;
percolator = myAClass.getSuperClassesList().iterator();
seen = new HashSet<PyClass>();
}
private AncestorsIterator(PyClassImpl AClass, Set<PyClass> seen) {
myAClass = AClass;
this.seen = seen;
percolator = myAClass.getSuperClassesList().iterator();
}
public boolean hasNext() {
@@ -563,7 +570,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
return ret;
}
if (percolator.hasNext()) {
PyClass it = percolator.next();
PyClassImpl it = (PyClassImpl)percolator.next();
if (seen.contains(it)) {
continue iterations; // loop back is equivalent to return next();
}
@@ -572,9 +579,9 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
return it;
}
else if (pending.size() > 0) {
PyClass it = pending.get(0);
PyClassImpl it = pending.get(0);
pending.remove(0); // t, ts* = pending
percolator = it.iterateAncestors().iterator();
percolator = new AncestorsIterator(it, new HashSet<PyClass>(seen));
// loop back is equivalent to return next();
}
else return null;
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
</problems>
@@ -0,0 +1,4 @@
from seob import SeoB
class SeoA(SeoB):
pass
@@ -0,0 +1,4 @@
from seoa import SeoA
class SeoB(SeoA):
pass
@@ -16,7 +16,7 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
doTest(getTestName(true), inspection);
}
private void doTest(String testName, LocalInspectionTool localInspectionTool) throws Throwable {
private void doTest(String testName, LocalInspectionTool localInspectionTool) throws Exception {
myFixture.testInspection("inspections/" + testName, new LocalInspectionToolWrapper(localInspectionTool));
}
@@ -180,4 +180,9 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
LocalInspectionTool inspection = new PyTupleItemAssignmentInspection();
doTest(getTestName(false), inspection);
}
public void testPyInitNewSignatureInspection() throws Exception {
LocalInspectionTool inspection = new PyInitNewSignatureInspection();
doTest(getTestName(false), inspection);
}
}