Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5ef8170

Browse files
committed
Python: CG trace: restructure QL for new XML format
1 parent c2748bf commit 5ef8170

3 files changed

Lines changed: 79 additions & 52 deletions

File tree

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,4 @@
11
import RecordedCalls
22

3-
import semmle.python.objects.Callables
4-
5-
from ValidRecordedCall rc, Call call, Value calleeValue
6-
where
7-
call = rc.getCall() and
8-
calleeValue.getACall() = call.getAFlowNode() and
9-
(
10-
rc instanceof RecordedPythonCall and
11-
calleeValue.(PythonFunctionValue).getScope() = rc.(RecordedPythonCall).getCallee()
12-
or
13-
rc instanceof RecordedBuiltinCall and
14-
calleeValue.(BuiltinFunctionObjectInternal).getBuiltin() = rc.(RecordedBuiltinCall).getCallee()
15-
or
16-
rc instanceof RecordedBuiltinCall and
17-
calleeValue.(BuiltinMethodObjectInternal).getBuiltin() = rc.(RecordedBuiltinCall).getCallee()
18-
)
19-
select call, "-->", calleeValue
3+
from PointsToBasedCallGraph::ResolvableRecordedCall rc
4+
select rc.getCall(), "-->", rc.getCalleeValue()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import RecordedCalls
2+
3+
from ValidRecordedCall rc
4+
where not rc instanceof PointsToBasedCallGraph::ResolvableRecordedCall
5+
select rc
Lines changed: 72 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,72 @@
11
import python
2-
32
import semmle.python.types.Builtins
3+
import semmle.python.objects.Callables
44

5-
class RecordedCall extends XMLElement {
6-
RecordedCall() { this.hasName("recorded_call") }
5+
class XMLRecordedCall extends XMLElement {
6+
XMLRecordedCall() { this.hasName("recorded_call") }
77

8-
string call_filename() { result = this.getAttributeValue("call_filename") }
8+
Call getCall() {
9+
result = this.getXMLCall().getCall()
10+
}
911

10-
int call_linenum() { result = this.getAttributeValue("call_linenum").toInt() }
12+
XMLCall getXMLCall() { result.getParent() = this }
13+
14+
XMLCallee getXMLCallee() { result.getParent() = this }
15+
}
1116

12-
int call_inst_index() { result = this.getAttributeValue("call_inst_index").toInt() }
17+
class XMLCall extends XMLElement {
18+
XMLCall() { this.hasName("Call") }
19+
20+
string get_filename_data() { result = this.getAChild("filename").getTextValue() }
21+
22+
int get_linenum_data() { result = this.getAChild("linenum").getTextValue().toInt() }
23+
24+
int get_inst_index_data() { result = this.getAChild("inst_index").getTextValue().toInt() }
1325

1426
Call getCall() {
15-
// TODO: handle calls spanning multiple lines
16-
result.getLocation().hasLocationInfo(this.call_filename(), this.call_linenum(), _, _, _)
27+
// TODO: do we handle calls spanning multiple lines?
28+
result.getLocation().hasLocationInfo(this.get_filename_data(), this.get_linenum_data(), _, _, _)
1729
}
1830
}
1931

20-
class RecordedPythonCall extends RecordedCall {
21-
RecordedPythonCall() {
22-
this.hasAttribute("pythoncallee_filename") and
23-
this.hasAttribute("pythoncallee_linenum") and
24-
this.hasAttribute("pythoncallee_funcname")
25-
}
32+
abstract class XMLCallee extends XMLElement { }
2633

27-
string pythoncallee_filename() { result = this.getAttributeValue("pythoncallee_filename") }
34+
class XMLPythonCallee extends XMLCallee {
35+
XMLPythonCallee() { this.hasName("PythonCallee") }
2836

29-
int pythoncallee_linenum() { result = this.getAttributeValue("pythoncallee_linenum").toInt() }
37+
string get_filename_data() { result = this.getAChild("filename").getTextValue() }
3038

31-
string pythoncallee_funcname() { result = this.getAttributeValue("pythoncallee_funcname") }
39+
int get_linenum_data() { result = this.getAChild("linenum").getTextValue().toInt() }
40+
41+
string get_funcname_data() { result = this.getAChild("funcname").getTextValue() }
3242

3343
Function getCallee() {
34-
result.getLocation().hasLocationInfo(this.pythoncallee_filename(), this.pythoncallee_linenum(), _, _, _)
44+
result.getLocation().hasLocationInfo(this.get_filename_data(), this.get_linenum_data(), _, _, _)
3545
}
3646
}
3747

38-
class RecordedBuiltinCall extends RecordedCall {
39-
RecordedBuiltinCall() {
40-
this.hasAttribute("externalcallee_module") and
41-
this.hasAttribute("externalcallee_qualname") and
42-
this.getAttributeValue("externalcallee_is_builtin") = "True"
43-
}
48+
class XMLExternalCallee extends XMLCallee {
49+
XMLExternalCallee() { this.hasName("ExternalCallee") }
4450

45-
string externalcallee_module() { result = this.getAttributeValue("externalcallee_module") }
51+
string get_module_data() { result = this.getAChild("module").getTextValue() }
4652

47-
string externalcallee_qualname() { result = this.getAttributeValue("externalcallee_qualname") }
53+
string get_qualname_data() { result = this.getAChild("qualname").getTextValue() }
4854

4955
Builtin getCallee() {
5056
exists(Builtin mod |
51-
not externalcallee_module() = "None" and
57+
not this.get_module_data() = "None" and
5258
mod.isModule() and
53-
mod.getName() = this.externalcallee_module()
59+
mod.getName() = this.get_module_data()
5460
or
55-
externalcallee_module() = "None" and
61+
this.get_module_data() = "None" and
5662
mod = Builtin::builtinModule()
5763
|
58-
result = traverse_qualname(mod, this.externalcallee_qualname())
64+
result = traverse_qualname(mod, this.get_qualname_data())
5965
)
6066
}
6167
}
6268

63-
Builtin traverse_qualname(Builtin parent, string qualname) {
69+
private Builtin traverse_qualname(Builtin parent, string qualname) {
6470
not qualname = "__objclass__" and
6571
not qualname.matches("%.%") and
6672
result = parent.getMember(qualname)
@@ -74,17 +80,48 @@ Builtin traverse_qualname(Builtin parent, string qualname) {
7480
)
7581
}
7682

77-
7883
/**
7984
* Class of recorded calls where we can uniquely identify both the `call` and the `callee`.
8085
*/
81-
class ValidRecordedCall extends RecordedCall {
86+
class ValidRecordedCall extends XMLRecordedCall {
8287
ValidRecordedCall() {
8388
strictcount(this.getCall()) = 1 and
8489
(
85-
strictcount(this.(RecordedPythonCall).getCall()) = 1
90+
strictcount(this.getXMLCallee().(XMLPythonCallee).getCallee()) = 1
8691
or
87-
strictcount(this.(RecordedBuiltinCall).getCall()) = 1
92+
strictcount(this.getXMLCallee().(XMLExternalCallee).getCallee()) = 1
8893
)
8994
}
9095
}
96+
97+
class InvalidRecordedCall extends XMLRecordedCall {
98+
InvalidRecordedCall() { not this instanceof ValidRecordedCall }
99+
}
100+
101+
module PointsToBasedCallGraph {
102+
class ResolvableRecordedCall extends ValidRecordedCall {
103+
Value calleeValue;
104+
105+
ResolvableRecordedCall() {
106+
exists(Call call, XMLCallee xmlCallee |
107+
call = this.getCall() and
108+
calleeValue.getACall() = call.getAFlowNode() and
109+
xmlCallee = this.getXMLCallee() and
110+
(
111+
xmlCallee instanceof XMLPythonCallee and
112+
calleeValue.(PythonFunctionValue).getScope() = xmlCallee.(XMLPythonCallee).getCallee()
113+
or
114+
xmlCallee instanceof XMLExternalCallee and
115+
calleeValue.(BuiltinFunctionObjectInternal).getBuiltin() =
116+
xmlCallee.(XMLExternalCallee).getCallee()
117+
or
118+
xmlCallee instanceof XMLExternalCallee and
119+
calleeValue.(BuiltinMethodObjectInternal).getBuiltin() =
120+
xmlCallee.(XMLExternalCallee).getCallee()
121+
)
122+
)
123+
}
124+
125+
Value getCalleeValue() { result = calleeValue }
126+
}
127+
}

0 commit comments

Comments
 (0)