Skip to content

Commit 5087c8d

Browse files
authored
Merge pull request #297 from microsoft/jb1/flowstack-refactor
refactor: {Data,TaintTracking}FlowStack
2 parents 12969dd + 4bf4363 commit 5087c8d

File tree

6 files changed

+75
-542
lines changed

6 files changed

+75
-542
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/DataFlowStack.qll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import csharp
22
private import codeql.dataflow.DataFlow
33
private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific
4-
private import codeql.dataflowstack.DataFlowStack as DFS
4+
private import codeql.dataflowstack.FlowStack as FlowStack
55

6-
module LanguageDataFlowStack = DFS::LanguageDataFlow<Location, CsharpDataFlow>;
6+
module LanguageFlowStack = FlowStack::LanguageDataFlow<Location, CsharpDataFlow>;
77

88
private module FlowStackInput<DataFlow::ConfigSig Config>
9-
implements LanguageDataFlowStack::DataFlowGroup<Config>::DataFlowStackSig<DataFlow::Global<Config>>
9+
implements LanguageFlowStack::DataFlowConfigContext<Config>::FlowInstance
1010
{
1111
private module Flow = DataFlow::Global<Config>;
12+
class PathNode = Flow::PathNode;
1213

1314
CsharpDataFlow::Node getNode(Flow::PathNode n) { result = n.getNode() }
1415

@@ -26,12 +27,12 @@ private module FlowStackInput<DataFlow::ConfigSig Config>
2627
}
2728

2829
module DataFlowStackMake<DataFlow::ConfigSig Config> {
29-
import LanguageDataFlowStack::FlowStack<DataFlow::Global<Config>, Config, FlowStackInput<Config>>
30+
import LanguageFlowStack::FlowStack<Config, FlowStackInput<Config>>
3031
}
3132

3233
module BiStackAnalysisMake<
3334
DataFlow::ConfigSig ConfigA,
3435
DataFlow::ConfigSig ConfigB
3536
>{
36-
import LanguageDataFlowStack::BiStackAnalysis<ConfigA, DataFlow::Global<ConfigA>, FlowStackInput<ConfigA>, ConfigB, DataFlow::Global<ConfigB>, FlowStackInput<ConfigB>>
37+
import LanguageFlowStack::BiStackAnalysis<ConfigA, FlowStackInput<ConfigA>, ConfigB, FlowStackInput<ConfigB>>
3738
}

csharp/ql/lib/semmle/code/csharp/dataflow/TaintTrackingStack.qll

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import csharp
22
private import codeql.dataflow.DataFlow
33
private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific
44
private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific
5-
private import codeql.dataflowstack.TaintTrackingStack as TTS
5+
private import codeql.dataflowstack.FlowStack as FlowStack
66

7-
module LanguageTaintTrackingStack = TTS::LanguageTaintTracking<Location, CsharpDataFlow, CsharpTaintTracking>;
7+
module LanguageFlowStack = FlowStack::LanguageDataFlow<Location, CsharpDataFlow>;
88

9-
private module TaintTrackingStackInput<DataFlow::ConfigSig Config>
10-
implements LanguageTaintTrackingStack::DataFlowGroup<Config>::TaintTrackingStackSig<TaintTracking::Global<Config>>
9+
private module FlowStackInput<DataFlow::ConfigSig Config>
10+
implements LanguageFlowStack::DataFlowConfigContext<Config>::FlowInstance
1111
{
1212
private module Flow = TaintTracking::Global<Config>;
13+
class PathNode = Flow::PathNode;
1314

1415
CsharpDataFlow::Node getNode(Flow::PathNode n) { result = n.getNode() }
1516

@@ -27,12 +28,12 @@ private module TaintTrackingStackInput<DataFlow::ConfigSig Config>
2728
}
2829

2930
module DataFlowStackMake<DataFlow::ConfigSig Config> {
30-
import LanguageTaintTrackingStack::FlowStack<TaintTracking::Global<Config>, Config, TaintTrackingStackInput<Config>>
31+
import LanguageFlowStack::FlowStack<Config, FlowStackInput<Config>>
3132
}
3233

3334
module BiStackAnalysisMake<
3435
DataFlow::ConfigSig ConfigA,
3536
DataFlow::ConfigSig ConfigB
3637
>{
37-
import LanguageTaintTrackingStack::BiStackAnalysis<ConfigA, TaintTracking::Global<ConfigA>, TaintTrackingStackInput<ConfigA>, ConfigB, TaintTracking::Global<ConfigB>, TaintTrackingStackInput<ConfigB>>
38+
import LanguageFlowStack::BiStackAnalysis<ConfigA, FlowStackInput<ConfigA>, ConfigB, FlowStackInput<ConfigB>>
3839
}

java/ql/lib/semmle/code/java/dataflow/DataFlowStack.qll

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,21 @@ module;
44
import java
55
private import semmle.code.java.dataflow.DataFlow
66
private import semmle.code.java.dataflow.internal.DataFlowImplSpecific
7-
private import codeql.dataflowstack.DataFlowStack as DFS
7+
private import codeql.dataflowstack.FlowStack as FlowStack
88

9-
module LanguageDataFlowStack = DFS::LanguageDataFlow<Location, JavaDataFlow>;
9+
module LanguageFlowStack = FlowStack::LanguageDataFlow<Location, JavaDataFlow>;
1010

1111
private module FlowStackInput<DataFlow::ConfigSig Config>
12-
implements LanguageDataFlowStack::DataFlowGroup<Config>::DataFlowStackSig<DataFlow::Global<Config>>
12+
implements LanguageFlowStack::DataFlowConfigContext<Config>::FlowInstance
1313
{
1414
private module Flow = DataFlow::Global<Config>;
15+
class PathNode = Flow::PathNode;
1516

16-
JavaDataFlow::Node getNode(Flow::PathNode n) { result = n.getNode() }
17+
JavaDataFlow::Node getNode(PathNode n) { result = n.getNode() }
1718

18-
predicate isSource(Flow::PathNode n) { n.isSource() }
19+
predicate isSource(PathNode n) { n.isSource() }
1920

20-
Flow::PathNode getASuccessor(Flow::PathNode n) { result = n.getASuccessor() }
21+
PathNode getASuccessor(PathNode n) { result = n.getASuccessor() }
2122

2223
JavaDataFlow::DataFlowCallable getARuntimeTarget(JavaDataFlow::DataFlowCall call) {
2324
result.asCallable() = call.asCall().getCallee()
@@ -29,12 +30,12 @@ private module FlowStackInput<DataFlow::ConfigSig Config>
2930
}
3031

3132
module DataFlowStackMake<DataFlow::ConfigSig Config> {
32-
import LanguageDataFlowStack::FlowStack<DataFlow::Global<Config>, Config, FlowStackInput<Config>>
33+
import LanguageFlowStack::FlowStack<Config, FlowStackInput<Config>>
3334
}
3435

3536
module BiStackAnalysisMake<
3637
DataFlow::ConfigSig ConfigA,
3738
DataFlow::ConfigSig ConfigB
3839
>{
39-
import LanguageDataFlowStack::BiStackAnalysis<ConfigA, DataFlow::Global<ConfigA>, FlowStackInput<ConfigA>, ConfigB, DataFlow::Global<ConfigB>, FlowStackInput<ConfigB>>
40+
import LanguageFlowStack::BiStackAnalysis<ConfigA, FlowStackInput<ConfigA>, ConfigB, FlowStackInput<ConfigB>>
4041
}

java/ql/lib/semmle/code/java/dataflow/TaintTrackingStack.qll

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@ private import semmle.code.java.dataflow.DataFlow
66
private import semmle.code.java.dataflow.TaintTracking
77
private import semmle.code.java.dataflow.internal.DataFlowImplSpecific
88
private import semmle.code.java.dataflow.internal.TaintTrackingImplSpecific
9-
private import codeql.dataflowstack.TaintTrackingStack as TTS
9+
private import codeql.dataflowstack.FlowStack as FlowStack
1010

11-
module LanguageTaintTrackingStack = TTS::LanguageTaintTracking<Location, JavaDataFlow, JavaTaintTracking>;
11+
module LanguageFlowStack = FlowStack::LanguageDataFlow<Location, JavaDataFlow>;
1212

13-
private module TaintTrackingStackInput<DataFlow::ConfigSig Config>
14-
implements LanguageTaintTrackingStack::DataFlowGroup<Config>::TaintTrackingStackSig<TaintTracking::Global<Config>>
13+
private module FlowStackInput<DataFlow::ConfigSig Config>
14+
implements LanguageFlowStack::DataFlowConfigContext<Config>::FlowInstance
1515
{
1616
private module Flow = TaintTracking::Global<Config>;
17+
class PathNode = Flow::PathNode;
1718

18-
JavaDataFlow::Node getNode(Flow::PathNode n) { result = n.getNode() }
19+
JavaDataFlow::Node getNode(PathNode n) { result = n.getNode() }
1920

20-
predicate isSource(Flow::PathNode n) { n.isSource() }
21+
predicate isSource(PathNode n) { n.isSource() }
2122

22-
Flow::PathNode getASuccessor(Flow::PathNode n) { result = n.getASuccessor() }
23+
PathNode getASuccessor(PathNode n) { result = n.getASuccessor() }
2324

2425
JavaDataFlow::DataFlowCallable getARuntimeTarget(JavaDataFlow::DataFlowCall call) {
2526
result.asCallable() = call.asCall().getCallee()
@@ -31,12 +32,12 @@ private module TaintTrackingStackInput<DataFlow::ConfigSig Config>
3132
}
3233

3334
module DataFlowStackMake<DataFlow::ConfigSig Config> {
34-
import LanguageTaintTrackingStack::FlowStack<TaintTracking::Global<Config>, Config, TaintTrackingStackInput<Config>>
35+
import LanguageFlowStack::FlowStack<Config, FlowStackInput<Config>>
3536
}
3637

3738
module BiStackAnalysisMake<
3839
DataFlow::ConfigSig ConfigA,
3940
DataFlow::ConfigSig ConfigB
4041
>{
41-
import LanguageTaintTrackingStack::BiStackAnalysis<ConfigA, TaintTracking::Global<ConfigA>, TaintTrackingStackInput<ConfigA>, ConfigB, TaintTracking::Global<ConfigB>, TaintTrackingStackInput<ConfigB>>
42+
import LanguageFlowStack::BiStackAnalysis<ConfigA, FlowStackInput<ConfigA>, ConfigB, FlowStackInput<ConfigB>>
4243
}

shared/dataflowstack/codeql/dataflowstack/DataFlowStack.qll renamed to shared/dataflowstack/codeql/dataflowstack/FlowStack.qll

Lines changed: 43 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,53 @@ overlay[local?]
22
module;
33

44
private import codeql.dataflow.DataFlow as DF
5+
private import codeql.dataflow.TaintTracking as TT
56
private import codeql.util.Location
67

78
/**
8-
* A Language-initialized grouping of DataFlow types and primitives.
9+
* A Language-initialized grouping of DataFlow/TaintFlow types and primitives.
910
*/
1011
module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
1112
module AbstractDF = DF::Configs<Location, Lang>;
1213
module AbstractDataFlow = DF::DataFlowMake<Location, Lang>;
1314
module AbstractDataFlowOverlay = DF::DataFlowMakeOverlay<Location, Lang>;
1415

1516
/**
16-
* A collection of modules that are scoped to a specific DataFlow config implementation
17+
* Signatures and modules bound by a common DataFlow Config
1718
*/
18-
module DataFlowGroup<AbstractDF::ConfigSig Config>{
19+
module DataFlowConfigContext<AbstractDF::ConfigSig Config>{
1920

20-
module MyConfig = Config;
21-
module DataFlowGlobal = AbstractDataFlow::Global<Config>;
22-
module DataFlowOverlayGlobal = AbstractDataFlowOverlay::Global<Config>;
21+
signature module FlowInstance{
22+
class PathNode;
2323

24-
/**
25-
* A Taint tracking implementation, paramaterized over a DataFlow type
26-
*/
27-
signature module DataFlowStackSig<AbstractDataFlow::GlobalFlowSig GlobalFlow>{
24+
Lang::Node getNode(PathNode n);
2825

29-
Lang::Node getNode(GlobalFlow::PathNode n);
26+
predicate isSource(PathNode n);
3027

31-
predicate isSource(GlobalFlow::PathNode n);
32-
33-
GlobalFlow::PathNode getASuccessor(
34-
GlobalFlow::PathNode n
35-
);
28+
PathNode getASuccessor(PathNode n);
3629

3730
Lang::DataFlowCallable getARuntimeTarget(Lang::DataFlowCall call);
3831

3932
Lang::Node getAnArgumentNode(Lang::DataFlowCall call);
4033
}
34+
35+
module TaintFlowContext<TT::InputSig<Location, Lang> TTLang>{
36+
module AbstractTaintFlow = TT::TaintFlowMake<Location, Lang, TTLang>;
37+
module AbstractTaintFlowOverlay = TT::TaintFlowMakeOverlay<Location, Lang, TTLang>;
38+
module TaintFlowGlobal = AbstractTaintFlow::Global<Config>;
39+
module TaintFlowOverlayGlobal = AbstractTaintFlowOverlay::Global<Config>;
40+
}
4141
}
4242

4343
module BiStackAnalysis<
4444
AbstractDF::ConfigSig ConfigA,
45-
AbstractDataFlow::GlobalFlowSig GlobalFlowA,
46-
DataFlowGroup<ConfigA>::DataFlowStackSig<GlobalFlowA> TaintTrackingStackA,
45+
DataFlowConfigContext<ConfigA>::FlowInstance FlowA,
4746
AbstractDF::ConfigSig ConfigB,
48-
AbstractDataFlow::GlobalFlowSig GlobalFlowB,
49-
DataFlowGroup<ConfigB>::DataFlowStackSig<GlobalFlowB> TaintTrackingStackB>
47+
DataFlowConfigContext<ConfigB>::FlowInstance FlowB>
5048
{
51-
module FlowA = GlobalFlowA;
52-
53-
module FlowStackA = FlowStack<GlobalFlowA, ConfigA, TaintTrackingStackA>;
49+
module FlowStackA = FlowStack<ConfigA, FlowA>;
5450

55-
module FlowB = GlobalFlowB;
56-
57-
module FlowStackB = FlowStack<GlobalFlowB, ConfigB, TaintTrackingStackB>;
51+
module FlowStackB = FlowStack<ConfigB, FlowB>;
5852

5953
/**
6054
* Holds if either the Stack associated with `sourceNodeA` is a subset of the stack associated with `sourceNodeB`
@@ -72,10 +66,10 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
7266
flowStackA = FlowStackA::createFlowStack(sourceNodeA, sinkNodeA) and
7367
flowStackB = FlowStackB::createFlowStack(sourceNodeB, sinkNodeB) and
7468
(
75-
BiStackAnalysisImpl<GlobalFlowA, ConfigA, TaintTrackingStackA, GlobalFlowB, ConfigB, TaintTrackingStackB>::flowStackIsSubsetOf(flowStackA,
69+
BiStackAnalysisImpl<ConfigA, FlowA, ConfigB, FlowB>::flowStackIsSubsetOf(flowStackA,
7670
flowStackB)
7771
or
78-
BiStackAnalysisImpl<GlobalFlowB, ConfigB, TaintTrackingStackB, GlobalFlowA, ConfigA, TaintTrackingStackA>::flowStackIsSubsetOf(flowStackB,
72+
BiStackAnalysisImpl<ConfigB, FlowB, ConfigA, FlowA>::flowStackIsSubsetOf(flowStackB,
7973
flowStackA)
8074
)
8175
)
@@ -100,10 +94,10 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
10094
flowStackA = FlowStackA::createFlowStack(sourceNodeA, sinkNodeA) and
10195
flowStackB = FlowStackB::createFlowStack(sourceNodeB, sinkNodeB) and
10296
(
103-
BiStackAnalysisImpl<GlobalFlowA, ConfigA, TaintTrackingStackA, GlobalFlowB, ConfigB, TaintTrackingStackB>::flowStackIsConvergingTerminatingSubsetOf(flowStackA,
97+
BiStackAnalysisImpl<ConfigA, FlowA, ConfigB, FlowB>::flowStackIsConvergingTerminatingSubsetOf(flowStackA,
10498
flowStackB)
10599
or
106-
BiStackAnalysisImpl<GlobalFlowB, ConfigB, TaintTrackingStackB, GlobalFlowA, ConfigA, TaintTrackingStackA>::flowStackIsConvergingTerminatingSubsetOf(flowStackB,
100+
BiStackAnalysisImpl<ConfigB, FlowB, ConfigA, FlowA>::flowStackIsConvergingTerminatingSubsetOf(flowStackB,
107101
flowStackA)
108102
)
109103
)
@@ -116,7 +110,7 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
116110
* The top of stackA is in stackB and the bottom of stackA is then some successor further down stackB.
117111
*/
118112
predicate flowStackIsSubsetOf(FlowStackA::FlowStack flowStackA, FlowStackB::FlowStack flowStackB) {
119-
BiStackAnalysisImpl<GlobalFlowA, ConfigA, TaintTrackingStackA, GlobalFlowB, ConfigB, TaintTrackingStackB>::flowStackIsSubsetOf(flowStackA,
113+
BiStackAnalysisImpl<ConfigA, FlowA, ConfigB, FlowB>::flowStackIsSubsetOf(flowStackA,
120114
flowStackB)
121115
}
122116

@@ -128,23 +122,21 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
128122
predicate flowStackIsConvergingTerminatingSubsetOf(
129123
FlowStackA::FlowStack flowStackA, FlowStackB::FlowStack flowStackB
130124
) {
131-
BiStackAnalysisImpl<GlobalFlowA, ConfigA, TaintTrackingStackA, GlobalFlowB, ConfigB, TaintTrackingStackB>::flowStackIsConvergingTerminatingSubsetOf(flowStackA,
125+
BiStackAnalysisImpl<ConfigA, FlowA, ConfigB, FlowB>::flowStackIsConvergingTerminatingSubsetOf(flowStackA,
132126
flowStackB)
133127
}
134128
}
135129

136130
private module BiStackAnalysisImpl<
137-
AbstractDataFlow::GlobalFlowSig GlobalFlowA,
138131
AbstractDF::ConfigSig ConfigA,
139-
DataFlowGroup<ConfigA>::DataFlowStackSig<GlobalFlowA> DataFlowStackA,
140-
AbstractDataFlow::GlobalFlowSig GlobalFlowB,
132+
DataFlowConfigContext<ConfigA>::FlowInstance FlowA,
141133
AbstractDF::ConfigSig ConfigB,
142-
DataFlowGroup<ConfigB>::DataFlowStackSig<GlobalFlowB> DataFlowStackB>
134+
DataFlowConfigContext<ConfigB>::FlowInstance FlowB>
143135
{
144136

145-
module FlowStackA = FlowStack<GlobalFlowA, ConfigA, DataFlowStackA>;
137+
module FlowStackA = FlowStack<ConfigA, FlowA>;
146138

147-
module FlowStackB = FlowStack<GlobalFlowB, ConfigB, DataFlowStackB>;
139+
module FlowStackB = FlowStack<ConfigB, FlowB>;
148140

149141
/**
150142
* Holds if stackA is a subset of stackB,
@@ -189,30 +181,25 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
189181
}
190182

191183
module FlowStack<
192-
AbstractDataFlow::GlobalFlowSig GlobalFlow,
193184
AbstractDF::ConfigSig Config,
194-
DataFlowGroup<Config>::DataFlowStackSig<GlobalFlow> TaintTrackingStack>
195-
{
196-
private module Flow = GlobalFlow;
185+
DataFlowConfigContext<Config>::FlowInstance Flow>{
197186

198187
/**
199188
* Determines whether or not the given PathNode is a source
200-
* TODO: Refactor to Flow::PathNode signature
201189
*/
202-
predicate isSource(Flow::PathNode node) { TaintTrackingStack::isSource(node) }
190+
predicate isSource = Flow::isSource/1;
203191

204192
/**
205193
* Determines whether or not the given PathNode is a sink
206-
* TODO: Refactor to Flow::PathNode signature
207194
*/
208-
predicate isSink(Flow::PathNode node) { not exists(TaintTrackingStack::getASuccessor(node)) }
195+
predicate isSink(Flow::PathNode node) { not exists(Flow::getASuccessor(node)) }
209196

210197
/** A FlowStack encapsulates flows between a source and a sink, and all the pathways inbetween (possibly multiple) */
211198
private newtype FlowStackType =
212199
TFlowStack(Flow::PathNode source, Flow::PathNode sink) {
213-
TaintTrackingStack::isSource(source) and
214-
not exists(TaintTrackingStack::getASuccessor(sink)) and
215-
TaintTrackingStack::getASuccessor*(source) = sink
200+
Flow::isSource(source) and
201+
not exists(Flow::getASuccessor(sink)) and
202+
Flow::getASuccessor*(source) = sink
216203
}
217204

218205
class FlowStack extends FlowStackType, TFlowStack {
@@ -261,8 +248,8 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
261248
TFlowStackFrame(FlowStack flowStack, CallFrame frame) {
262249
exists(Flow::PathNode source, Flow::PathNode sink |
263250
flowStack = TFlowStack(source, sink) and
264-
frame.getPathNode() = TaintTrackingStack::getASuccessor*(source) and
265-
TaintTrackingStack::getASuccessor*(frame.getPathNode()) = sink
251+
frame.getPathNode() = Flow::getASuccessor*(source) and
252+
Flow::getASuccessor*(frame.getPathNode()) = sink
266253
)
267254
}
268255

@@ -305,7 +292,7 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
305292
FlowStackFrame getChildStackFrame() {
306293
exists(FlowStackFrame transitiveSuccessor |
307294
transitiveSuccessor = this.getASuccessor+() and
308-
TaintTrackingStack::getARuntimeTarget(this.getCall()) =
295+
Flow::getARuntimeTarget(this.getCall()) =
309296
transitiveSuccessor.getCall().getEnclosingCallable() and
310297
result = transitiveSuccessor
311298
)
@@ -338,7 +325,7 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
338325
private newtype TCallFrameType =
339326
TCallFrame(Flow::PathNode node) {
340327
exists(Lang::DataFlowCall c |
341-
TaintTrackingStack::getAnArgumentNode(c) = TaintTrackingStack::getNode(node)
328+
Flow::getAnArgumentNode(c) = Flow::getNode(node)
342329
)
343330
}
344331

@@ -374,7 +361,7 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
374361
Lang::DataFlowCall getCall() {
375362
exists(Lang::DataFlowCall call, Flow::PathNode node |
376363
this = TCallFrame(node) and
377-
TaintTrackingStack::getAnArgumentNode(call) = TaintTrackingStack::getNode(node) and
364+
Flow::getAnArgumentNode(call) = Flow::getNode(node) and
378365
result = call
379366
)
380367
}
@@ -396,10 +383,10 @@ module LanguageDataFlow<LocationSig Location, DF::InputSig<Location> Lang>{
396383
*/
397384
private Flow::PathNode getSuccessorCall(Flow::PathNode n) {
398385
exists(Flow::PathNode succ |
399-
succ = TaintTrackingStack::getASuccessor(n) and
386+
succ = Flow::getASuccessor(n) and
400387
if
401388
exists(Lang::DataFlowCall c |
402-
TaintTrackingStack::getAnArgumentNode(c) = TaintTrackingStack::getNode(succ)
389+
Flow::getAnArgumentNode(c) = Flow::getNode(succ)
403390
)
404391
then result = succ
405392
else result = getSuccessorCall(succ)

0 commit comments

Comments
 (0)