Skip to content

Commit 9c50acc

Browse files
authored
Merge pull request github#3602 from MathiasVP/path-problem-for-dataflow-tests
C++: Make path-problem versions of ir-flow.ql and flow.ql
2 parents 8b3dd6d + 2a1ba6d commit 9c50acc

File tree

8 files changed

+1060
-66
lines changed

8 files changed

+1060
-66
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
private import semmle.code.cpp.dataflow.DataFlow
2+
private import DataFlow
3+
4+
class Conf extends Configuration {
5+
Conf() { this = "FieldFlowConf" }
6+
7+
override predicate isSource(Node src) {
8+
src.asExpr() instanceof NewExpr
9+
or
10+
src.asExpr().(Call).getTarget().hasName("user_input")
11+
or
12+
exists(FunctionCall fc |
13+
fc.getAnArgument() = src.asDefiningArgument() and
14+
fc.getTarget().hasName("argument_source")
15+
)
16+
}
17+
18+
override predicate isSink(Node sink) {
19+
exists(Call c |
20+
c.getTarget().hasName("sink") and
21+
c.getAnArgument() = sink.asExpr()
22+
)
23+
}
24+
25+
override predicate isAdditionalFlowStep(Node a, Node b) {
26+
b.asPartialDefinition() =
27+
any(Call c | c.getTarget().hasName("insert") and c.getAnArgument() = a.asExpr())
28+
.getQualifier()
29+
or
30+
b.asExpr().(AddressOfExpr).getOperand() = a.asExpr()
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
private import semmle.code.cpp.ir.dataflow.DataFlow
2+
private import DataFlow
3+
4+
class Conf extends Configuration {
5+
Conf() { this = "FieldFlowConf" }
6+
7+
override predicate isSource(Node src) {
8+
src.asExpr() instanceof NewExpr
9+
or
10+
src.asExpr().(Call).getTarget().hasName("user_input")
11+
or
12+
exists(FunctionCall fc |
13+
fc.getAnArgument() = src.asDefiningArgument() and
14+
fc.getTarget().hasName("argument_source")
15+
)
16+
}
17+
18+
override predicate isSink(Node sink) {
19+
exists(Call c |
20+
c.getTarget().hasName("sink") and
21+
c.getAnArgument() = sink.asExpr()
22+
)
23+
}
24+
25+
override predicate isAdditionalFlowStep(Node a, Node b) {
26+
b.asPartialDefinition() =
27+
any(Call c | c.getTarget().hasName("insert") and c.getAnArgument() = a.asExpr())
28+
.getQualifier()
29+
or
30+
b.asExpr().(AddressOfExpr).getOperand() = a.asExpr()
31+
}
32+
}

cpp/ql/test/library-tests/dataflow/fields/flow.ql

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,19 @@
44

55
import TestUtilities.InlineExpectationsTest
66
import semmle.code.cpp.dataflow.DataFlow
7-
import DataFlow
7+
import ASTConfiguration
88
import cpp
99

10-
class Conf extends Configuration {
11-
Conf() { this = "FieldFlowConf" }
12-
13-
override predicate isSource(Node src) {
14-
src.asExpr() instanceof NewExpr
15-
or
16-
src.asExpr().(Call).getTarget().hasName("user_input")
17-
or
18-
exists(FunctionCall fc |
19-
fc.getAnArgument() = src.asDefiningArgument() and
20-
fc.getTarget().hasName("argument_source")
21-
)
22-
}
23-
24-
override predicate isSink(Node sink) {
25-
exists(Call c |
26-
c.getTarget().hasName("sink") and
27-
c.getAnArgument() = sink.asExpr()
28-
)
29-
}
30-
31-
override predicate isAdditionalFlowStep(Node a, Node b) {
32-
b.asPartialDefinition() =
33-
any(Call c | c.getTarget().hasName("insert") and c.getAnArgument() = a.asExpr())
34-
.getQualifier()
35-
or
36-
b.asExpr().(AddressOfExpr).getOperand() = a.asExpr()
37-
}
38-
}
39-
4010
class ASTFieldFlowTest extends InlineExpectationsTest {
4111
ASTFieldFlowTest() { this = "ASTFieldFlowTest" }
4212

4313
override string getARelevantTag() { result = "ast" }
4414

4515
override predicate hasActualResult(Location location, string element, string tag, string value) {
46-
exists(Node source, Node sink, Conf conf, int n |
16+
exists(DataFlow::Node source, DataFlow::Node sink, Conf conf, int n |
4717
tag = "ast" and
4818
conf.hasFlow(source, sink) and
49-
n = strictcount(Node otherSource | conf.hasFlow(otherSource, sink)) and
19+
n = strictcount(DataFlow::Node otherSource | conf.hasFlow(otherSource, sink)) and
5020
(
5121
n = 1 and value = ""
5222
or

cpp/ql/test/library-tests/dataflow/fields/ir-flow.ql

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,19 @@
44

55
import TestUtilities.InlineExpectationsTest
66
import semmle.code.cpp.ir.dataflow.DataFlow
7-
import DataFlow
7+
import IRConfiguration
88
import cpp
99

10-
class Conf extends Configuration {
11-
Conf() { this = "FieldFlowConf" }
12-
13-
override predicate isSource(Node src) {
14-
src.asExpr() instanceof NewExpr
15-
or
16-
src.asExpr().(Call).getTarget().hasName("user_input")
17-
or
18-
exists(FunctionCall fc |
19-
fc.getAnArgument() = src.asDefiningArgument() and
20-
fc.getTarget().hasName("argument_source")
21-
)
22-
}
23-
24-
override predicate isSink(Node sink) {
25-
exists(Call c |
26-
c.getTarget().hasName("sink") and
27-
c.getAnArgument() = sink.asExpr()
28-
)
29-
}
30-
31-
override predicate isAdditionalFlowStep(Node a, Node b) {
32-
b.asPartialDefinition() =
33-
any(Call c | c.getTarget().hasName("insert") and c.getAnArgument() = a.asExpr())
34-
.getQualifier()
35-
or
36-
b.asExpr().(AddressOfExpr).getOperand() = a.asExpr()
37-
}
38-
}
39-
4010
class IRFieldFlowTest extends InlineExpectationsTest {
4111
IRFieldFlowTest() { this = "IRFieldFlowTest" }
4212

4313
override string getARelevantTag() { result = "ir" }
4414

4515
override predicate hasActualResult(Location location, string element, string tag, string value) {
46-
exists(Node source, Node sink, Conf conf, int n |
16+
exists(DataFlow::Node source, DataFlow::Node sink, Conf conf, int n |
4717
tag = "ir" and
4818
conf.hasFlow(source, sink) and
49-
n = strictcount(Node otherSource | conf.hasFlow(otherSource, sink)) and
19+
n = strictcount(DataFlow::Node otherSource | conf.hasFlow(otherSource, sink)) and
5020
(
5121
n = 1 and value = ""
5222
or
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
edges
2+
| A.cpp:142:7:142:20 | Chi [c] | A.cpp:151:18:151:18 | D output argument [c] |
3+
| A.cpp:142:7:142:20 | Store | A.cpp:142:7:142:20 | Chi [c] |
4+
| A.cpp:142:14:142:20 | new | A.cpp:142:7:142:20 | Store |
5+
| A.cpp:151:18:151:18 | Chi [c] | A.cpp:154:13:154:13 | c |
6+
| A.cpp:151:18:151:18 | Chi [c] | A.cpp:154:13:154:13 | c |
7+
| A.cpp:151:18:151:18 | D output argument [c] | A.cpp:151:18:151:18 | Chi [c] |
8+
| A.cpp:154:13:154:13 | c | A.cpp:154:10:154:13 | (void *)... |
9+
| aliasing.cpp:9:3:9:22 | Chi [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] |
10+
| aliasing.cpp:9:3:9:22 | Store | aliasing.cpp:9:3:9:22 | Chi [m1] |
11+
| aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:9:3:9:22 | Store |
12+
| aliasing.cpp:13:3:13:21 | Chi [m1] | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] |
13+
| aliasing.cpp:13:3:13:21 | Store | aliasing.cpp:13:3:13:21 | Chi [m1] |
14+
| aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:13:3:13:21 | Store |
15+
| aliasing.cpp:25:17:25:19 | Chi [m1] | aliasing.cpp:29:11:29:12 | m1 |
16+
| aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | aliasing.cpp:25:17:25:19 | Chi [m1] |
17+
| aliasing.cpp:26:19:26:20 | Chi [m1] | aliasing.cpp:30:11:30:12 | m1 |
18+
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | aliasing.cpp:26:19:26:20 | Chi [m1] |
19+
| aliasing.cpp:37:13:37:22 | call to user_input | aliasing.cpp:38:11:38:12 | m1 |
20+
| aliasing.cpp:42:11:42:20 | call to user_input | aliasing.cpp:43:13:43:14 | m1 |
21+
| aliasing.cpp:60:3:60:22 | Chi [m1] | aliasing.cpp:61:13:61:14 | Store [m1] |
22+
| aliasing.cpp:60:3:60:22 | Store | aliasing.cpp:60:3:60:22 | Chi [m1] |
23+
| aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:3:60:22 | Store |
24+
| aliasing.cpp:61:13:61:14 | Store [m1] | aliasing.cpp:62:14:62:15 | m1 |
25+
| aliasing.cpp:79:11:79:20 | call to user_input | aliasing.cpp:80:12:80:13 | m1 |
26+
| aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 |
27+
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 |
28+
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] |
29+
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] |
30+
| by_reference.cpp:84:3:84:25 | Store | by_reference.cpp:84:3:84:25 | Chi [a] |
31+
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:84:3:84:25 | Store |
32+
| by_reference.cpp:88:3:88:24 | Chi [a] | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] |
33+
| by_reference.cpp:88:3:88:24 | Chi [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] |
34+
| by_reference.cpp:88:3:88:24 | Store | by_reference.cpp:88:3:88:24 | Chi [a] |
35+
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | Store |
36+
| by_reference.cpp:102:21:102:39 | Chi [a] | by_reference.cpp:110:27:110:27 | a |
37+
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | by_reference.cpp:102:21:102:39 | Chi [a] |
38+
| by_reference.cpp:106:21:106:41 | Chi [a] | by_reference.cpp:114:29:114:29 | a |
39+
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | by_reference.cpp:106:21:106:41 | Chi [a] |
40+
| by_reference.cpp:122:21:122:38 | Chi [a] | by_reference.cpp:130:27:130:27 | a |
41+
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:21:122:38 | Chi [a] |
42+
| by_reference.cpp:126:21:126:40 | Chi [a] | by_reference.cpp:134:29:134:29 | a |
43+
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | by_reference.cpp:126:21:126:40 | Chi [a] |
44+
| simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] |
45+
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] |
46+
| simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i |
47+
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:22:11:22:11 | a |
48+
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a |
49+
nodes
50+
| A.cpp:142:7:142:20 | Chi [c] | semmle.label | Chi [c] |
51+
| A.cpp:142:7:142:20 | Store | semmle.label | Store |
52+
| A.cpp:142:14:142:20 | new | semmle.label | new |
53+
| A.cpp:151:18:151:18 | Chi [c] | semmle.label | Chi [c] |
54+
| A.cpp:151:18:151:18 | D output argument [c] | semmle.label | D output argument [c] |
55+
| A.cpp:154:10:154:13 | (void *)... | semmle.label | (void *)... |
56+
| A.cpp:154:13:154:13 | c | semmle.label | c |
57+
| A.cpp:154:13:154:13 | c | semmle.label | c |
58+
| aliasing.cpp:9:3:9:22 | Chi [m1] | semmle.label | Chi [m1] |
59+
| aliasing.cpp:9:3:9:22 | Store | semmle.label | Store |
60+
| aliasing.cpp:9:11:9:20 | call to user_input | semmle.label | call to user_input |
61+
| aliasing.cpp:13:3:13:21 | Chi [m1] | semmle.label | Chi [m1] |
62+
| aliasing.cpp:13:3:13:21 | Store | semmle.label | Store |
63+
| aliasing.cpp:13:10:13:19 | call to user_input | semmle.label | call to user_input |
64+
| aliasing.cpp:25:17:25:19 | Chi [m1] | semmle.label | Chi [m1] |
65+
| aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | semmle.label | pointerSetter output argument [m1] |
66+
| aliasing.cpp:26:19:26:20 | Chi [m1] | semmle.label | Chi [m1] |
67+
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | semmle.label | referenceSetter output argument [m1] |
68+
| aliasing.cpp:29:11:29:12 | m1 | semmle.label | m1 |
69+
| aliasing.cpp:30:11:30:12 | m1 | semmle.label | m1 |
70+
| aliasing.cpp:37:13:37:22 | call to user_input | semmle.label | call to user_input |
71+
| aliasing.cpp:38:11:38:12 | m1 | semmle.label | m1 |
72+
| aliasing.cpp:42:11:42:20 | call to user_input | semmle.label | call to user_input |
73+
| aliasing.cpp:43:13:43:14 | m1 | semmle.label | m1 |
74+
| aliasing.cpp:60:3:60:22 | Chi [m1] | semmle.label | Chi [m1] |
75+
| aliasing.cpp:60:3:60:22 | Store | semmle.label | Store |
76+
| aliasing.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input |
77+
| aliasing.cpp:61:13:61:14 | Store [m1] | semmle.label | Store [m1] |
78+
| aliasing.cpp:62:14:62:15 | m1 | semmle.label | m1 |
79+
| aliasing.cpp:79:11:79:20 | call to user_input | semmle.label | call to user_input |
80+
| aliasing.cpp:80:12:80:13 | m1 | semmle.label | m1 |
81+
| aliasing.cpp:86:10:86:19 | call to user_input | semmle.label | call to user_input |
82+
| aliasing.cpp:87:12:87:13 | m1 | semmle.label | m1 |
83+
| aliasing.cpp:92:12:92:21 | call to user_input | semmle.label | call to user_input |
84+
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
85+
| by_reference.cpp:84:3:84:25 | Chi [a] | semmle.label | Chi [a] |
86+
| by_reference.cpp:84:3:84:25 | Store | semmle.label | Store |
87+
| by_reference.cpp:84:14:84:23 | call to user_input | semmle.label | call to user_input |
88+
| by_reference.cpp:88:3:88:24 | Chi [a] | semmle.label | Chi [a] |
89+
| by_reference.cpp:88:3:88:24 | Store | semmle.label | Store |
90+
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
91+
| by_reference.cpp:102:21:102:39 | Chi [a] | semmle.label | Chi [a] |
92+
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
93+
| by_reference.cpp:106:21:106:41 | Chi [a] | semmle.label | Chi [a] |
94+
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
95+
| by_reference.cpp:110:27:110:27 | a | semmle.label | a |
96+
| by_reference.cpp:114:29:114:29 | a | semmle.label | a |
97+
| by_reference.cpp:122:21:122:38 | Chi [a] | semmle.label | Chi [a] |
98+
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
99+
| by_reference.cpp:126:21:126:40 | Chi [a] | semmle.label | Chi [a] |
100+
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
101+
| by_reference.cpp:130:27:130:27 | a | semmle.label | a |
102+
| by_reference.cpp:134:29:134:29 | a | semmle.label | a |
103+
| simple.cpp:65:5:65:22 | Store [i] | semmle.label | Store [i] |
104+
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
105+
| simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] |
106+
| simple.cpp:67:13:67:13 | i | semmle.label | i |
107+
| struct_init.c:20:20:20:29 | call to user_input | semmle.label | call to user_input |
108+
| struct_init.c:22:11:22:11 | a | semmle.label | a |
109+
| struct_init.c:27:7:27:16 | call to user_input | semmle.label | call to user_input |
110+
| struct_init.c:31:23:31:23 | a | semmle.label | a |
111+
#select
112+
| A.cpp:154:10:154:13 | (void *)... | A.cpp:142:14:142:20 | new | A.cpp:154:10:154:13 | (void *)... | (void *)... flows from $@ | A.cpp:142:14:142:20 | new | new |
113+
| A.cpp:154:13:154:13 | c | A.cpp:142:14:142:20 | new | A.cpp:154:13:154:13 | c | c flows from $@ | A.cpp:142:14:142:20 | new | new |
114+
| aliasing.cpp:29:11:29:12 | m1 | aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:29:11:29:12 | m1 | m1 flows from $@ | aliasing.cpp:9:11:9:20 | call to user_input | call to user_input |
115+
| aliasing.cpp:30:11:30:12 | m1 | aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:30:11:30:12 | m1 | m1 flows from $@ | aliasing.cpp:13:10:13:19 | call to user_input | call to user_input |
116+
| aliasing.cpp:38:11:38:12 | m1 | aliasing.cpp:37:13:37:22 | call to user_input | aliasing.cpp:38:11:38:12 | m1 | m1 flows from $@ | aliasing.cpp:37:13:37:22 | call to user_input | call to user_input |
117+
| aliasing.cpp:43:13:43:14 | m1 | aliasing.cpp:42:11:42:20 | call to user_input | aliasing.cpp:43:13:43:14 | m1 | m1 flows from $@ | aliasing.cpp:42:11:42:20 | call to user_input | call to user_input |
118+
| aliasing.cpp:62:14:62:15 | m1 | aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:62:14:62:15 | m1 | m1 flows from $@ | aliasing.cpp:60:11:60:20 | call to user_input | call to user_input |
119+
| aliasing.cpp:80:12:80:13 | m1 | aliasing.cpp:79:11:79:20 | call to user_input | aliasing.cpp:80:12:80:13 | m1 | m1 flows from $@ | aliasing.cpp:79:11:79:20 | call to user_input | call to user_input |
120+
| aliasing.cpp:87:12:87:13 | m1 | aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 | m1 flows from $@ | aliasing.cpp:86:10:86:19 | call to user_input | call to user_input |
121+
| aliasing.cpp:93:12:93:13 | m1 | aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 | m1 flows from $@ | aliasing.cpp:92:12:92:21 | call to user_input | call to user_input |
122+
| by_reference.cpp:110:27:110:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:110:27:110:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
123+
| by_reference.cpp:114:29:114:29 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:114:29:114:29 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
124+
| by_reference.cpp:130:27:130:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:130:27:130:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
125+
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
126+
| simple.cpp:67:13:67:13 | i | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:67:13:67:13 | i | i flows from $@ | simple.cpp:65:11:65:20 | call to user_input | call to user_input |
127+
| struct_init.c:22:11:22:11 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:22:11:22:11 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
128+
| struct_init.c:31:23:31:23 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* @kind path-problem
3+
*/
4+
5+
import semmle.code.cpp.ir.dataflow.DataFlow
6+
import IRConfiguration
7+
import cpp
8+
import DataFlow::PathGraph
9+
10+
from DataFlow::PathNode src, DataFlow::PathNode sink, Conf conf
11+
where conf.hasFlowPath(src, sink)
12+
select sink, src, sink, sink + " flows from $@", src, src.toString()

0 commit comments

Comments
 (0)