Skip to content

Commit 54f53c8

Browse files
committed
Python: Refactor argumentRoutingTest.ql to be more generic
I checked to see that the tests still works. If I deleted the `arg5` annotation, it got failures: ```diff diff --git a/python/ql/test/experimental/dataflow/coverage/argumentPassing.py b/python/ql/test/experimental/dataflow/coverage/argumentPassing.py index e218bdd..71816c1e01 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentPassing.py +++ b/python/ql/test/experimental/dataflow/coverage/argumentPassing.py @@ -46,7 +46,7 @@ def argument_passing( c, d=arg4, #$ arg4 func=argument_passing *, - e=arg5, #$ arg5 func=argument_passing + e=arg5, f, **g, ): diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected b/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected index e69de29..22037a40c3 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected @@ -0,0 +1,2 @@ +| argumentPassing.py:49:7:49:10 | ControlFlowNode for arg5 | Unexpected result: arg5= | +| argumentPassing.py:49:7:49:10 | ControlFlowNode for arg5 | Unexpected result: func=argument_passing | ```
1 parent 76f3d74 commit 54f53c8

File tree

1 file changed

+21
-182
lines changed

1 file changed

+21
-182
lines changed

python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.ql

Lines changed: 21 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -46,209 +46,48 @@ class Argument1RoutingConfig extends DataFlow::Configuration {
4646
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
4747
}
4848

49-
class Argument2RoutingTest extends RoutingTest {
50-
Argument2RoutingTest() { this = "Argument2RoutingTest" }
49+
// for argument 2 and up, we use a generic approach. Change `maxNumArgs` below if we
50+
// need to increase the maximum number of arguments.
51+
private int maxNumArgs() { result = 7 }
5152

52-
override string flowTag() { result = "arg2" }
53+
class RestArgumentRoutingTest extends RoutingTest {
54+
int argNumber;
5355

54-
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
55-
exists(Argument2RoutingConfig cfg | cfg.hasFlow(source, sink))
56-
}
57-
}
58-
59-
/**
60-
* A configuration to check routing of arguments through magic methods.
61-
*/
62-
class Argument2RoutingConfig extends DataFlow::Configuration {
63-
Argument2RoutingConfig() { this = "Argument2RoutingConfig" }
64-
65-
override predicate isSource(DataFlow::Node node) {
66-
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg2"
67-
}
68-
69-
override predicate isSink(DataFlow::Node node) {
70-
exists(CallNode call |
71-
call.getFunction().(NameNode).getId() = "SINK2" and
72-
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
73-
)
74-
}
75-
76-
/**
77-
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
78-
* Use-use flow lets the argument to the first call reach the sink inside the second call,
79-
* making it seem like we handle all cases even if we only handle the last one.
80-
* We make the test honest by preventing flow into source nodes.
81-
*/
82-
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
83-
}
84-
85-
class Argument3RoutingTest extends RoutingTest {
86-
Argument3RoutingTest() { this = "Argument3RoutingTest" }
87-
88-
override string flowTag() { result = "arg3" }
89-
90-
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
91-
exists(Argument3RoutingConfig cfg | cfg.hasFlow(source, sink))
92-
}
93-
}
94-
95-
/**
96-
* A configuration to check routing of arguments through magic methods.
97-
*/
98-
class Argument3RoutingConfig extends DataFlow::Configuration {
99-
Argument3RoutingConfig() { this = "Argument3RoutingConfig" }
100-
101-
override predicate isSource(DataFlow::Node node) {
102-
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg3"
103-
}
104-
105-
override predicate isSink(DataFlow::Node node) {
106-
exists(CallNode call |
107-
call.getFunction().(NameNode).getId() = "SINK3" and
108-
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
109-
)
110-
}
111-
112-
/**
113-
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
114-
* Use-use flow lets the argument to the first call reach the sink inside the second call,
115-
* making it seem like we handle all cases even if we only handle the last one.
116-
* We make the test honest by preventing flow into source nodes.
117-
*/
118-
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
119-
}
120-
121-
class Argument4RoutingTest extends RoutingTest {
122-
Argument4RoutingTest() { this = "Argument4RoutingTest" }
123-
124-
override string flowTag() { result = "arg4" }
125-
126-
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
127-
exists(Argument4RoutingConfig cfg | cfg.hasFlow(source, sink))
128-
}
129-
}
130-
131-
/**
132-
* A configuration to check routing of arguments through magic methods.
133-
*/
134-
class Argument4RoutingConfig extends DataFlow::Configuration {
135-
Argument4RoutingConfig() { this = "Argument4RoutingConfig" }
136-
137-
override predicate isSource(DataFlow::Node node) {
138-
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg4"
139-
}
140-
141-
override predicate isSink(DataFlow::Node node) {
142-
exists(CallNode call |
143-
call.getFunction().(NameNode).getId() = "SINK4" and
144-
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
145-
)
56+
RestArgumentRoutingTest() {
57+
argNumber in [2 .. maxNumArgs()] and
58+
this = "Argument" + argNumber + "RoutingTest"
14659
}
14760

148-
/**
149-
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
150-
* Use-use flow lets the argument to the first call reach the sink inside the second call,
151-
* making it seem like we handle all cases even if we only handle the last one.
152-
* We make the test honest by preventing flow into source nodes.
153-
*/
154-
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
155-
}
156-
157-
class Argument5RoutingTest extends RoutingTest {
158-
Argument5RoutingTest() { this = "Argument5RoutingTest" }
159-
160-
override string flowTag() { result = "arg5" }
61+
override string flowTag() { result = "arg" + argNumber }
16162

16263
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
163-
exists(Argument5RoutingConfig cfg | cfg.hasFlow(source, sink))
164-
}
165-
}
166-
167-
/**
168-
* A configuration to check routing of arguments through magic methods.
169-
*/
170-
class Argument5RoutingConfig extends DataFlow::Configuration {
171-
Argument5RoutingConfig() { this = "Argument5RoutingConfig" }
172-
173-
override predicate isSource(DataFlow::Node node) {
174-
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg5"
175-
}
176-
177-
override predicate isSink(DataFlow::Node node) {
178-
exists(CallNode call |
179-
call.getFunction().(NameNode).getId() = "SINK5" and
180-
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
64+
exists(RestArgumentRoutingConfig cfg | cfg.getArgNumber() = argNumber |
65+
cfg.hasFlow(source, sink)
18166
)
18267
}
183-
184-
/**
185-
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
186-
* Use-use flow lets the argument to the first call reach the sink inside the second call,
187-
* making it seem like we handle all cases even if we only handle the last one.
188-
* We make the test honest by preventing flow into source nodes.
189-
*/
190-
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
191-
}
192-
193-
class Argument6RoutingTest extends RoutingTest {
194-
Argument6RoutingTest() { this = "Argument6RoutingTest" }
195-
196-
override string flowTag() { result = "arg6" }
197-
198-
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
199-
exists(Argument6RoutingConfig cfg | cfg.hasFlow(source, sink))
200-
}
20168
}
20269

20370
/**
20471
* A configuration to check routing of arguments through magic methods.
20572
*/
206-
class Argument6RoutingConfig extends DataFlow::Configuration {
207-
Argument6RoutingConfig() { this = "Argument6RoutingConfig" }
73+
class RestArgumentRoutingConfig extends DataFlow::Configuration {
74+
int argNumber;
20875

209-
override predicate isSource(DataFlow::Node node) {
210-
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg6"
76+
RestArgumentRoutingConfig() {
77+
argNumber in [2 .. maxNumArgs()] and
78+
this = "Argument" + argNumber + "RoutingConfig"
21179
}
21280

213-
override predicate isSink(DataFlow::Node node) {
214-
exists(CallNode call |
215-
call.getFunction().(NameNode).getId() = "SINK6" and
216-
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
217-
)
218-
}
219-
220-
/**
221-
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
222-
* Use-use flow lets the argument to the first call reach the sink inside the second call,
223-
* making it seem like we handle all cases even if we only handle the last one.
224-
* We make the test honest by preventing flow into source nodes.
225-
*/
226-
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
227-
}
228-
229-
class Argument7RoutingTest extends RoutingTest {
230-
Argument7RoutingTest() { this = "Argument7RoutingTest" }
231-
232-
override string flowTag() { result = "arg7" }
233-
234-
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
235-
exists(Argument7RoutingConfig cfg | cfg.hasFlow(source, sink))
236-
}
237-
}
238-
239-
/**
240-
* A configuration to check routing of arguments through magic methods.
241-
*/
242-
class Argument7RoutingConfig extends DataFlow::Configuration {
243-
Argument7RoutingConfig() { this = "Argument7RoutingConfig" }
81+
/** Gets the argument number this configuration is for. */
82+
int getArgNumber() { result = argNumber }
24483

24584
override predicate isSource(DataFlow::Node node) {
246-
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg7"
85+
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg" + argNumber
24786
}
24887

24988
override predicate isSink(DataFlow::Node node) {
25089
exists(CallNode call |
251-
call.getFunction().(NameNode).getId() = "SINK7" and
90+
call.getFunction().(NameNode).getId() = "SINK" + argNumber and
25291
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
25392
)
25493
}
@@ -259,5 +98,5 @@ class Argument7RoutingConfig extends DataFlow::Configuration {
25998
* making it seem like we handle all cases even if we only handle the last one.
26099
* We make the test honest by preventing flow into source nodes.
261100
*/
262-
override predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
101+
override predicate isBarrierIn(DataFlow::Node node) { this.isSource(node) }
263102
}

0 commit comments

Comments
 (0)