Skip to content

Commit d41b86a

Browse files
committed
UniversalFlow: Tweak visibility and add qldoc.
1 parent 6680537 commit d41b86a

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

shared/typeflow/codeql/typeflow/UniversalFlow.qll

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
/**
2+
* Provides predicates for proving data flow properties that hold for all
3+
* paths, that is, reachability is computed using universal quantification over
4+
* the step relation.
5+
*
6+
* Regular data flow search for the existence of a path, that is, reachability
7+
* using existential quantification over the step relation. Hence, this library
8+
* computes the dual reachability predicate that states that a certain property
9+
* always holds for a given node regardless of the path taken.
10+
*
11+
* As a simple comparison, the computed predicate is essentially equivalent to
12+
* the folllowing:
13+
* ```ql
14+
* predicate hasProperty(FlowNode n, Prop t) {
15+
* basecase(n, t)
16+
* or
17+
* forex(FlowNode mid | step(mid, n) | hasProperty(mid, t))
18+
* }
19+
* ```
20+
* More complex property propagation is supported, and strongly connected
21+
* components in the flow graph are handled.
22+
*
23+
* As an initial such property calculation, the library computes the set of
24+
* nodes that are always null. These are then subtracted from the graph such
25+
* that subsequently calculated properties hold under the assumption that the
26+
* value is not null.
27+
*/
28+
129
private import codeql.util.Location
230
private import codeql.util.Unit
331

@@ -59,13 +87,21 @@ module UfMake<LocationSig Location, UniversalFlowInput<Location> I> {
5987
)
6088
}
6189

62-
/**
63-
* Holds if data can flow from `n1` to `n2` in one step, `n1` is not necessarily
64-
* functionally determined by `n2`, and `n1` might take a non-null value.
65-
*/
66-
predicate joinStepNotNull(FlowNode n1, FlowNode n2) { joinStep(n1, n2) and not isNull(n1) }
90+
private import Internal
6791

68-
predicate anyStep(FlowNode n1, FlowNode n2) { joinStepNotNull(n1, n2) or uniqStep(n1, n2) }
92+
module Internal {
93+
/**
94+
* Holds if data can flow from `n1` to `n2` in one step, `n1` is not necessarily
95+
* functionally determined by `n2`, and `n1` might take a non-null value.
96+
*/
97+
predicate joinStepNotNull(FlowNode n1, FlowNode n2) { joinStep(n1, n2) and not isNull(n1) }
98+
99+
/**
100+
* Holds if data can flow from `n1` to `n2` in one step, excluding join
101+
* steps from nodes that are always null.
102+
*/
103+
predicate anyStep(FlowNode n1, FlowNode n2) { joinStepNotNull(n1, n2) or uniqStep(n1, n2) }
104+
}
69105

70106
private predicate sccEdge(FlowNode n1, FlowNode n2) { anyStep(n1, n2) and anyStep+(n2, n1) }
71107

shared/typeflow/codeql/typeflow/internal/TypeFlowImpl.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ module TypeFlow<LocationSig Location, TypeFlowInput<Location> I> {
162162
*/
163163
private predicate unionTypeFlowBaseCand(TypeFlowNode n, Type t, boolean exact) {
164164
exists(TypeFlowNode next |
165-
UnivFlow::joinStepNotNull(n, next) and
165+
UnivFlow::Internal::joinStepNotNull(n, next) and
166166
bestTypeFlowOrTypeFlowBase(n, t, exact) and
167167
not bestTypeFlowOrTypeFlowBase(next, t, exact) and
168168
not exactType(next, _)
@@ -196,7 +196,7 @@ module TypeFlow<LocationSig Location, TypeFlowInput<Location> I> {
196196
private predicate unionTypeFlow0(TypeFlowNode n, Type t, boolean exact) {
197197
hasUnionTypeFlow(n) and
198198
(
199-
exists(TypeFlowNode mid | UnivFlow::anyStep(mid, n) | unionTypeFlow(mid, t, exact))
199+
exists(TypeFlowNode mid | UnivFlow::Internal::anyStep(mid, n) | unionTypeFlow(mid, t, exact))
200200
or
201201
unionTypeFlowBaseCand(n, t, exact)
202202
or

0 commit comments

Comments
 (0)