Skip to content

Commit aa66b9b

Browse files
committed
Dataflow: Align more predicates.
1 parent 6e6e5d6 commit aa66b9b

File tree

1 file changed

+48
-13
lines changed

1 file changed

+48
-13
lines changed

java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,9 @@ private module Stage2 {
794794

795795
class CcCall extends Cc {
796796
CcCall() { this = true }
797+
798+
/** Holds if this call context may be `call`. */
799+
predicate matchesCall(DataFlowCall call) { any() }
797800
}
798801

799802
class CcNoCall extends Cc {
@@ -834,6 +837,9 @@ private module Stage2 {
834837

835838
private predicate flowIntoCall = flowIntoCallNodeCand1/5;
836839

840+
bindingset[ap, contentType]
841+
private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() }
842+
837843
/* Begin: Stage 2 logic. */
838844
private predicate flowCand(Node node, ApApprox apa, Configuration config) {
839845
PrevStage::revFlow(node, _, _, apa, config)
@@ -847,7 +853,8 @@ private module Stage2 {
847853
* argument in a call, and if so, `argAp` records the access path of that
848854
* argument.
849855
*/
850-
private predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
856+
pragma[nomagic]
857+
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
851858
flowCand(node, _, config) and
852859
config.isSource(node) and
853860
cc = ccAny() and
@@ -920,7 +927,8 @@ private module Stage2 {
920927
) {
921928
exists(DataFlowType contentType |
922929
fwdFlow(node1, cc, argAp, ap1, config) and
923-
PrevStage::storeStepCand(node1, getApprox(ap1), tc, node2, contentType, config)
930+
PrevStage::storeStepCand(node1, getApprox(ap1), tc, node2, contentType, config) and
931+
typecheckStore(ap1, contentType)
924932
)
925933
}
926934

@@ -1154,7 +1162,8 @@ private module Stage2 {
11541162
) {
11551163
exists(ReturnNodeExt ret, CcCall ccc |
11561164
revFlowOut(call, ret, toReturn, returnAp, ap, config) and
1157-
fwdFlow(ret, ccc, apSome(_), ap, config)
1165+
fwdFlow(ret, ccc, apSome(_), ap, config) and
1166+
ccc.matchesCall(call)
11581167
)
11591168
}
11601169

@@ -1391,6 +1400,9 @@ private module Stage3 {
13911400

13921401
class CcCall extends Cc {
13931402
CcCall() { this = true }
1403+
1404+
/** Holds if this call context may be `call`. */
1405+
predicate matchesCall(DataFlowCall call) { any() }
13941406
}
13951407

13961408
class CcNoCall extends Cc {
@@ -1423,6 +1435,19 @@ private module Stage3 {
14231435

14241436
private predicate flowIntoCall = flowIntoCallNodeCand2/5;
14251437

1438+
bindingset[node, ap]
1439+
private predicate filter(Node node, Ap ap) {
1440+
not ap.isClearedAt(node) and
1441+
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
1442+
}
1443+
1444+
bindingset[ap, contentType]
1445+
private predicate typecheckStore(Ap ap, DataFlowType contentType) {
1446+
// We need to typecheck stores here, since reverse flow through a getter
1447+
// might have a different type here compared to inside the getter.
1448+
compatibleTypes(ap.getType(), contentType)
1449+
}
1450+
14261451
/* Begin: Stage 3 logic. */
14271452
private predicate flowCand(Node node, ApApprox apa, Configuration config) {
14281453
PrevStage::revFlow(node, _, _, apa, config)
@@ -1440,13 +1465,12 @@ private module Stage3 {
14401465
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
14411466
fwdFlow0(node, cc, argAp, ap, config) and
14421467
flowCand(node, unbindBool(getApprox(ap)), config) and
1443-
not ap.isClearedAt(node) and
1444-
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
1468+
filter(node, ap)
14451469
}
14461470

14471471
pragma[nomagic]
14481472
private predicate fwdFlow0(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
1449-
flowCand(node, false, config) and
1473+
flowCand(node, _, config) and
14501474
config.isSource(node) and
14511475
cc = ccAny() and
14521476
argAp = apNone() and
@@ -1519,9 +1543,7 @@ private module Stage3 {
15191543
exists(DataFlowType contentType |
15201544
fwdFlow(node1, cc, argAp, ap1, config) and
15211545
PrevStage::storeStepCand(node1, getApprox(ap1), tc, node2, contentType, config) and
1522-
// We need to typecheck stores here, since reverse flow through a getter
1523-
// might have a different type here compared to inside the getter.
1524-
compatibleTypes(ap1.getType(), contentType)
1546+
typecheckStore(ap1, contentType)
15251547
)
15261548
}
15271549

@@ -1749,7 +1771,8 @@ private module Stage3 {
17491771
) {
17501772
exists(ReturnNodeExt ret, CcCall ccc |
17511773
revFlowOut(call, ret, toReturn, returnAp, ap, config) and
1752-
fwdFlow(ret, ccc, apSome(_), ap, config)
1774+
fwdFlow(ret, ccc, apSome(_), ap, config) and
1775+
ccc.matchesCall(call)
17531776
)
17541777
}
17551778

@@ -1772,6 +1795,8 @@ private module Stage3 {
17721795
)
17731796
}
17741797

1798+
predicate revFlow(Node node, Configuration config) { revFlow(node, _, _, _, config) }
1799+
17751800
private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) {
17761801
storeStepFwd(_, ap, tc, _, _, config)
17771802
}
@@ -2105,6 +2130,12 @@ private module Stage4 {
21052130
PrevStage::revFlow(node1, _, _, _, unbind(config))
21062131
}
21072132

2133+
bindingset[node, ap]
2134+
private predicate filter(Node node, Ap ap) { any() }
2135+
2136+
bindingset[ap, contentType]
2137+
private predicate typecheckStore(Ap ap, DataFlowType contentType) { any() }
2138+
21082139
/* Begin: Stage 4 logic. */
21092140
private predicate flowCand(Node node, ApApprox apa, Configuration config) {
21102141
PrevStage::revFlow(node, _, _, apa, config)
@@ -2118,11 +2149,14 @@ private module Stage4 {
21182149
* argument in a call, and if so, `argAp` records the access path of that
21192150
* argument.
21202151
*/
2152+
pragma[nomagic]
21212153
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
21222154
fwdFlow0(node, cc, argAp, ap, config) and
2123-
flowCand(node, getApprox(ap), config)
2155+
flowCand(node, getApprox(ap), config) and
2156+
filter(node, ap)
21242157
}
21252158

2159+
pragma[nomagic]
21262160
private predicate fwdFlow0(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
21272161
flowCand(node, _, config) and
21282162
config.isSource(node) and
@@ -2196,7 +2230,8 @@ private module Stage4 {
21962230
) {
21972231
exists(DataFlowType contentType |
21982232
fwdFlow(node1, cc, argAp, ap1, config) and
2199-
PrevStage::storeStepCand(node1, getApprox(ap1), tc, node2, contentType, config)
2233+
PrevStage::storeStepCand(node1, getApprox(ap1), tc, node2, contentType, config) and
2234+
typecheckStore(ap1, contentType)
22002235
)
22012236
}
22022237

@@ -2448,7 +2483,7 @@ private module Stage4 {
24482483
)
24492484
}
24502485

2451-
predicate revFlow(Node n, Configuration config) { revFlow(n, _, _, _, config) }
2486+
predicate revFlow(Node node, Configuration config) { revFlow(node, _, _, _, config) }
24522487

24532488
private predicate fwdConsCand(TypedContent tc, Ap ap, Configuration config) {
24542489
storeStepFwd(_, ap, tc, _, _, config)

0 commit comments

Comments
 (0)