Skip to content

Commit b8d0b69

Browse files
committed
Dataflow: Introduce sink projection and add successor as member predicate.
1 parent bc1dd45 commit b8d0b69

File tree

1 file changed

+122
-21
lines changed

1 file changed

+122
-21
lines changed

shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll

Lines changed: 122 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2533,6 +2533,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25332533
fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) and
25342534
revFlow(node, state, _, _, ap)
25352535
} or
2536+
TStagePathNodeSink(NodeEx node, FlowState state) {
2537+
exists(StagePathNodeMid sink |
2538+
sink.isAtSink() and
2539+
node = sink.getNodeEx() and
2540+
state = sink.getState()
2541+
)
2542+
} or
25362543
TStagePathNodeSrcGrp() or
25372544
TStagePathNodeSinkGrp()
25382545

@@ -2542,12 +2549,16 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25422549
/** Gets the `FlowState` of this node. */
25432550
abstract FlowState getState();
25442551

2545-
/** Gets a textual representation of this element. */
2546-
abstract string toString();
2552+
/** Holds if this node is a source. */
2553+
abstract predicate isSource();
25472554

2548-
predicate isSource() { none() }
2555+
/** Holds if this node is a sink. */
2556+
predicate isSink() { this instanceof TStagePathNodeSink }
25492557

2550-
predicate isSink() { none() }
2558+
abstract StagePathNodeImpl getASuccessorImpl(string label);
2559+
2560+
/** Gets a textual representation of this element. */
2561+
abstract string toString();
25512562

25522563
/** Gets the location of this node. */
25532564
Location getLocation() { result = this.getNodeEx().getLocation() }
@@ -2565,6 +2576,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25652576
override NodeEx getNodeEx() { none() }
25662577

25672578
override FlowState getState() { none() }
2579+
2580+
override StagePathNodeImpl getASuccessorImpl(string label) {
2581+
result.isSource() and label = ""
2582+
}
2583+
2584+
override predicate isSource() { none() }
25682585
}
25692586

25702587
private class StagePathNodeSinkGrp extends StagePathNodeImpl, TStagePathNodeSinkGrp {
@@ -2575,6 +2592,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25752592
override NodeEx getNodeEx() { none() }
25762593

25772594
override FlowState getState() { none() }
2595+
2596+
override StagePathNodeImpl getASuccessorImpl(string label) { none() }
2597+
2598+
override predicate isSource() { none() }
25782599
}
25792600

25802601
/**
@@ -2599,6 +2620,48 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25992620

26002621
override FlowState getState() { result = state }
26012622

2623+
private StagePathNodeMid getSuccMid(string label) {
2624+
localStep(this, result, label)
2625+
or
2626+
nonLocalStep(this, result, label)
2627+
}
2628+
2629+
private predicate isSourceWithLabel(string labelprefix) {
2630+
exists(string model |
2631+
this.isSource() and
2632+
sourceModel(node, model) and
2633+
model != "" and
2634+
labelprefix = "Src:" + model + " "
2635+
)
2636+
}
2637+
2638+
override StagePathNodeImpl getASuccessorImpl(string label) {
2639+
// an intermediate step to another intermediate node
2640+
exists(string l2 | result = this.getSuccMid(l2) |
2641+
not this.isSourceWithLabel(_) and label = l2
2642+
or
2643+
exists(string l1 |
2644+
this.isSourceWithLabel(l1) and
2645+
label = l1 + l2
2646+
)
2647+
)
2648+
or
2649+
// a final step to a sink
2650+
exists(string l2, string sinkmodel |
2651+
result = this.getSuccMid(l2).projectToSink(sinkmodel)
2652+
|
2653+
not this.isSourceWithLabel(_) and
2654+
if sinkmodel != "" then label = l2 + " Sink:" + sinkmodel else label = l2
2655+
or
2656+
exists(string l1 |
2657+
this.isSourceWithLabel(l1) and
2658+
if sinkmodel != ""
2659+
then label = l1 + l2 + " Sink:" + sinkmodel
2660+
else label = l1 + l2
2661+
)
2662+
)
2663+
}
2664+
26022665
private string ppType() {
26032666
exists(string ppt | ppt = t.toString() |
26042667
if ppt = "" then result = "" else result = " : " + ppt
@@ -2642,7 +2705,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
26422705
ap instanceof ApNil
26432706
}
26442707

2645-
override predicate isSink() {
2708+
predicate isAtSink() {
26462709
sinkNode(node, state) and
26472710
ap instanceof ApNil and
26482711
// For `FeatureHasSinkCallContext` the condition `cc instanceof CallContextNoCall`
@@ -2662,6 +2725,37 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
26622725
then instanceofCcNoCall(cc)
26632726
else any()
26642727
}
2728+
2729+
StagePathNodeSink projectToSink(string model) {
2730+
this.isAtSink() and
2731+
sinkModel(node, model) and
2732+
result.getNodeEx() = node and
2733+
result.getState() = state
2734+
}
2735+
}
2736+
2737+
/**
2738+
* A flow graph node corresponding to a sink. This is disjoint from the
2739+
* intermediate nodes in order to uniquely correspond to a given sink by
2740+
* excluding the call context.
2741+
*/
2742+
private class StagePathNodeSink extends StagePathNodeImpl, TStagePathNodeSink {
2743+
NodeEx node;
2744+
FlowState state;
2745+
2746+
StagePathNodeSink() { this = TStagePathNodeSink(node, state) }
2747+
2748+
override NodeEx getNodeEx() { result = node }
2749+
2750+
override FlowState getState() { result = state }
2751+
2752+
override string toString() { result = node.toString() }
2753+
2754+
override StagePathNodeImpl getASuccessorImpl(string label) {
2755+
result.isArbitrarySink() and label = ""
2756+
}
2757+
2758+
override predicate isSource() { sourceNode(node, state) }
26652759
}
26662760

26672761
pragma[nomagic]
@@ -2795,7 +2889,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
27952889
) {
27962890
pn1 = pn2 and
27972891
summaryLabel = "" and
2798-
subpaths(_, pn1, _, _)
2892+
subpathsImpl(_, pn1, _, _)
27992893
or
28002894
exists(StagePathNodeImpl mid, string l1, string l2 |
28012895
summaryLabel(pn1, mid, l1) and
@@ -2806,7 +2900,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
28062900

28072901
private predicate summaryStep(StagePathNodeImpl arg, StagePathNodeImpl out, string label) {
28082902
exists(StagePathNodeImpl par, StagePathNodeImpl ret |
2809-
subpaths(arg, par, ret, out) and
2903+
subpathsImpl(arg, par, ret, out) and
28102904
summaryLabel(par, ret, label)
28112905
)
28122906
}
@@ -2881,30 +2975,37 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
28812975
)
28822976
}
28832977

2884-
query predicate subpaths(
2978+
/**
2979+
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
2980+
*
2981+
* All of the nodes may be hidden.
2982+
*/
2983+
private predicate subpathsImpl(
28852984
StagePathNodeImpl arg, StagePathNodeImpl par, StagePathNodeImpl ret,
28862985
StagePathNodeImpl out
28872986
) {
28882987
exists(
28892988
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
2890-
ApOption argAp, Typ t0, Ap ap
2989+
ApOption argAp, Typ t0, Ap ap, StagePathNodeImpl out0
28912990
|
28922991
fwdFlowThroughStep2(arg, par, ret, node, cc, state, summaryCtx, argT, argAp, t0, ap) and
2893-
out = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap)
2992+
out0 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap)
2993+
|
2994+
out = out0 or out = out0.(StagePathNodeMid).projectToSink(_)
28942995
)
28952996
}
28962997

2897-
query predicate edges(StagePathNodeImpl pn1, StagePathNodeImpl pn2, string key, string val) {
2898-
key = "provenance" and
2899-
(
2900-
localStep(pn1, pn2, val)
2901-
or
2902-
nonLocalStep(pn1, pn2, val)
2903-
or
2904-
pn1.isArbitrarySource() and pn2.isSource() and val = ""
2905-
or
2906-
pn1.isSink() and pn2.isArbitrarySink() and val = ""
2907-
)
2998+
module StagePathGraph {
2999+
predicate edges(StagePathNodeImpl a, StagePathNodeImpl b, string key, string val) {
3000+
a.getASuccessorImpl(val) = b and
3001+
key = "provenance"
3002+
}
3003+
3004+
query predicate nodes(StagePathNodeImpl n, string key, string val) {
3005+
key = "semmle.label" and val = n.toString()
3006+
}
3007+
3008+
query predicate subpaths = subpathsImpl/4;
29083009
}
29093010
}
29103011

0 commit comments

Comments
 (0)