mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
protect against SOE when iterating superclasses (PY-846)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user