Skip to content

Commit d7ea60e

Browse files
committed
Java: Move data flow lib.
1 parent 1c64fb1 commit d7ea60e

File tree

6 files changed

+259
-12
lines changed

6 files changed

+259
-12
lines changed

java/ql/lib/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ extractor: java
66
library: true
77
upgrades: upgrades
88
dependencies:
9+
codeql/dataflow: ${workspace}
910
codeql/mad: ${workspace}
1011
codeql/regex: ${workspace}
1112
codeql/tutorial: ${workspace}

java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll renamed to shared/dataflow/codeql/dataflow/DataFlow.qll

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
* through the `Global` and `GlobalWithState` modules.
66
*/
77

8-
private import DataFlowImplCommon
9-
private import DataFlowImplSpecific::Private
10-
import DataFlowImplSpecific::Public
11-
import DataFlowImplCommonPublic
12-
private import DataFlowImpl
8+
import DataFlowParameter
9+
10+
module Configs<DataFlowParameter Lang> {
11+
private import Lang
12+
private import DataFlowImplCommon::MakeImplCommon<Lang>
13+
import DataFlowImplCommonPublic
1314

1415
/** An input configuration for data flow. */
1516
signature module ConfigSig {
@@ -202,6 +203,13 @@ signature module StateConfigSig {
202203
default predicate includeHiddenNodes() { none() }
203204
}
204205

206+
}
207+
208+
module DataFlowMake<DataFlowParameter Lang> {
209+
private import Lang
210+
private import DataFlowImpl::MakeImpl<Lang>
211+
import Configs<Lang>
212+
205213
/**
206214
* Gets the exploration limit for `partialFlow` and `partialFlowRev`
207215
* measured in approximate number of interprocedural steps.
@@ -448,3 +456,4 @@ module MergePathGraph3<
448456
}
449457
}
450458
}
459+
}

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll renamed to shared/dataflow/codeql/dataflow/DataFlowImpl.qll

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@
44
* Provides an implementation of global (interprocedural) data flow.
55
*/
66

7-
private import DataFlowImplCommon
8-
private import DataFlowImplSpecific::Private
9-
private import DataFlowImplSpecific::Public
10-
private import DataFlowImplCommonPublic
117
private import codeql.util.Unit
128
private import codeql.util.Option
13-
import DataFlow
9+
10+
import DataFlowParameter
11+
12+
module MakeImpl<DataFlowParameter Lang> {
13+
private import Lang
14+
private import DataFlow::DataFlowMake<Lang>
15+
private import DataFlowImplCommon::MakeImplCommon<Lang>
16+
private import DataFlowImplCommonPublic
17+
18+
1419

1520
/**
1621
* An input configuration for data flow using flow state. This signature equals
@@ -4742,3 +4747,4 @@ module Impl<FullStateConfigSig Config> {
47424747
}
47434748
}
47444749
}
4750+
}

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll renamed to shared/dataflow/codeql/dataflow/DataFlowImplCommon.qll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
private import DataFlowImplSpecific::Private
2-
private import DataFlowImplSpecific::Public
1+
import DataFlowParameter
2+
3+
module MakeImplCommon<DataFlowParameter Lang> {
4+
private import Lang
35
import Cached
46

57
module DataFlowImplCommonPublic {
@@ -1479,3 +1481,4 @@ class AccessPathFrontOption extends TAccessPathFrontOption {
14791481
this = TAccessPathFrontSome(any(AccessPathFront apf | result = apf.toString()))
14801482
}
14811483
}
1484+
}
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
signature module DataFlowParameter {
2+
class Node {
3+
/** Gets a textual representation of this element. */
4+
string toString();
5+
6+
/**
7+
* Holds if this element is at the specified location.
8+
* The location spans column `startcolumn` of line `startline` to
9+
* column `endcolumn` of line `endline` in file `filepath`.
10+
* For more information, see
11+
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
12+
*/
13+
predicate hasLocationInfo(
14+
string filepath, int startline, int startcolumn, int endline, int endcolumn
15+
);
16+
}
17+
18+
class ParameterNode extends Node;
19+
20+
class ArgumentNode extends Node;
21+
22+
class ReturnNode extends Node {
23+
ReturnKind getKind();
24+
}
25+
26+
class OutNode extends Node;
27+
28+
class PostUpdateNode extends Node {
29+
Node getPreUpdateNode();
30+
}
31+
32+
class CastNode extends Node;
33+
34+
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos);
35+
36+
predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos);
37+
38+
DataFlowCallable nodeGetEnclosingCallable(Node node);
39+
40+
DataFlowType getNodeType(Node node);
41+
42+
predicate nodeIsHidden(Node node);
43+
44+
class DataFlowExpr;
45+
46+
/** Gets the node corresponding to `e`. */
47+
Node exprNode(DataFlowExpr e);
48+
49+
class DataFlowCall {
50+
/** Gets a textual representation of this element. */
51+
string toString();
52+
53+
DataFlowCallable getEnclosingCallable();
54+
}
55+
56+
class DataFlowCallable {
57+
/** Gets a textual representation of this element. */
58+
string toString();
59+
}
60+
61+
class ReturnKind {
62+
/** Gets a textual representation of this element. */
63+
string toString();
64+
}
65+
66+
/** Gets a viable implementation of the target of the given `Call`. */
67+
DataFlowCallable viableCallable(DataFlowCall c);
68+
69+
/**
70+
* Holds if the set of viable implementations that can be called by `call`
71+
* might be improved by knowing the call context.
72+
*/
73+
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c);
74+
75+
/**
76+
* Gets a viable dispatch target of `call` in the context `ctx`. This is
77+
* restricted to those `call`s for which a context might make a difference.
78+
*/
79+
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx);
80+
81+
/**
82+
* Gets a node that can read the value returned from `call` with return kind
83+
* `kind`.
84+
*/
85+
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind);
86+
87+
class DataFlowType {
88+
/** Gets a textual representation of this element. */
89+
string toString();
90+
}
91+
92+
string ppReprType(DataFlowType t);
93+
94+
bindingset[t1, t2]
95+
predicate compatibleTypes(DataFlowType t1, DataFlowType t2);
96+
97+
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2);
98+
99+
class Content {
100+
/** Gets a textual representation of this element. */
101+
string toString();
102+
}
103+
104+
predicate forceHighPrecision(Content c);
105+
106+
/**
107+
* An entity that represents a set of `Content`s.
108+
*
109+
* The set may be interpreted differently depending on whether it is
110+
* stored into (`getAStoreContent`) or read from (`getAReadContent`).
111+
*/
112+
class ContentSet {
113+
/** Gets a content that may be stored into when storing into this set. */
114+
Content getAStoreContent();
115+
116+
/** Gets a content that may be read from when reading from this set. */
117+
Content getAReadContent();
118+
}
119+
120+
class ContentApprox {
121+
/** Gets a textual representation of this element. */
122+
string toString();
123+
}
124+
125+
ContentApprox getContentApprox(Content c);
126+
127+
class ParameterPosition {
128+
/** Gets a textual representation of this element. */
129+
bindingset[this]
130+
string toString();
131+
}
132+
133+
class ArgumentPosition {
134+
/** Gets a textual representation of this element. */
135+
bindingset[this]
136+
string toString();
137+
}
138+
139+
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos);
140+
141+
predicate simpleLocalFlowStep(Node node1, Node node2);
142+
143+
/**
144+
* Holds if data can flow from `node1` to `node2` through a non-local step
145+
* that does not follow a call edge. For example, a step through a global
146+
* variable.
147+
*/
148+
predicate jumpStep(Node node1, Node node2);
149+
150+
/**
151+
* Holds if data can flow from `node1` to `node2` via a read of `c`. Thus,
152+
* `node1` references an object with a content `c.getAReadContent()` whose
153+
* value ends up in `node2`.
154+
*/
155+
predicate readStep(Node node1, ContentSet c, Node node2);
156+
157+
/**
158+
* Holds if data can flow from `node1` to `node2` via a store into `c`. Thus,
159+
* `node2` references an object with a content `c.getAStoreContent()` that
160+
* contains the value of `node1`.
161+
*/
162+
predicate storeStep(Node node1, ContentSet c, Node node2);
163+
164+
/**
165+
* Holds if values stored inside content `c` are cleared at node `n`. For example,
166+
* any value stored inside `f` is cleared at the pre-update node associated with `x`
167+
* in `x.f = newValue`.
168+
*/
169+
predicate clearsContent(Node n, ContentSet c);
170+
171+
/**
172+
* Holds if the value that is being tracked is expected to be stored inside content `c`
173+
* at node `n`.
174+
*/
175+
predicate expectsContent(Node n, ContentSet c);
176+
177+
/**
178+
* Holds if the node `n` is unreachable when the call context is `call`.
179+
*/
180+
predicate isUnreachableInCall(Node n, DataFlowCall call);
181+
182+
default int accessPathLimit() { result = 5 }
183+
184+
/**
185+
* Holds if flow is allowed to pass from parameter `p` and back to itself as a
186+
* side-effect, resulting in a summary from `p` to itself.
187+
*
188+
* One example would be to allow flow like `p.foo = p.bar;`, which is disallowed
189+
* by default as a heuristic.
190+
*/
191+
predicate allowParameterReturnInSelf(ParameterNode p);
192+
193+
class LambdaCallKind;
194+
195+
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
196+
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c);
197+
198+
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
199+
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver);
200+
201+
/** Extra data-flow steps needed for lambda flow analysis. */
202+
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue);
203+
204+
/**
205+
* Holds if `n` should never be skipped over in the `PathGraph` and in path
206+
* explanations.
207+
*/
208+
default predicate neverSkipInPathGraph(Node n) { none() }
209+
210+
/**
211+
* Gets an additional term that is added to the `join` and `branch` computations to reflect
212+
* an additional forward or backwards branching factor that is not taken into account
213+
* when calculating the (virtual) dispatch cost.
214+
*
215+
* Argument `arg` is part of a path from a source to a sink, and `p` is the target parameter.
216+
*/
217+
int getAdditionalFlowIntoCallNodeTerm(ArgumentNode arg, ParameterNode p);
218+
219+
predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg);
220+
}

shared/dataflow/qlpack.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name: codeql/dataflow
2+
version: 0.0.1-dev
3+
groups: shared
4+
library: true
5+
dependencies:
6+
codeql/ssa: ${workspace}
7+
codeql/util: ${workspace}
8+
warnOnImplicitThis: true

0 commit comments

Comments
 (0)