Skip to content

Commit f3ce578

Browse files
Filter out some results; for if the overridden method doesn't use self, or the call is last in the initialisation.
1 parent ed3cf84 commit f3ce578

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

python/ql/src/Classes/InitCallsSubclass/InitCallsSubclassMethod.ql

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,43 @@ predicate initSelfCall(Function init, DataFlow::MethodCallNode call) {
2525
)
2626
}
2727

28-
predicate initSelfCallOverridden(Function init, DataFlow::MethodCallNode call, Function override) {
29-
initSelfCall(init, call) and
30-
exists(Class superclass, Class subclass |
28+
predicate initSelfCallOverridden(
29+
Function init, DataFlow::MethodCallNode call, Function target, Function override
30+
) {
31+
init.isInitMethod() and
32+
call.getScope() = init and
33+
exists(Class superclass, Class subclass, DataFlow::Node self, DataFlow::ParameterNode selfArg |
3134
superclass = init.getScope() and
3235
subclass = override.getScope() and
3336
subclass = getADirectSubclass+(superclass) and
34-
call.calls(_, override.getName())
37+
selfArg.getParameter() = init.getArg(0) and
38+
DataFlow::localFlow(selfArg, self) and
39+
call.calls(self, override.getName()) and
40+
target = superclass.getAMethod() and
41+
target.getName() = override.getName() and
42+
not lastUse(self)
43+
)
44+
}
45+
46+
predicate lastUse(DataFlow::Node node) {
47+
not exists(DataFlow::Node next | DataFlow::localFlow(node, next) and node != next)
48+
}
49+
50+
predicate readsFromSelf(Function method) {
51+
exists(DataFlow::ParameterNode self, DataFlow::Node sink |
52+
self.getParameter() = method.getArg(0) and
53+
DataFlow::localFlow(self, sink)
54+
|
55+
sink instanceof DataFlow::ArgumentNode
56+
or
57+
sink = any(DataFlow::AttrRead a).getObject()
3558
)
3659
}
3760

38-
from Function init, DataFlow::MethodCallNode call, Function override
39-
where initSelfCallOverridden(init, call, override)
40-
select call,
41-
"This call to " + override.getName() + " in initialization method is overridden by " +
42-
override.getScope().getName() + ".$@.", override, override.getName()
61+
from Function init, DataFlow::MethodCallNode call, Function target, Function override
62+
where
63+
initSelfCallOverridden(init, call, target, override) and
64+
readsFromSelf(override) and
65+
not isClassmethod(override)
66+
select call, "This call to $@ in an initialization method is overridden by $@.", target,
67+
target.getQualifiedName(), override, override.getQualifiedName()

0 commit comments

Comments
 (0)