Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b0e5925

Browse files
committed
Dataflow: Refactor stage 3 conscand predicates.
1 parent 261ef0f commit b0e5925

2 files changed

Lines changed: 61 additions & 50 deletions

File tree

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

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,12 @@ private module Stage3 {
12411241

12421242
class ApNil = AccessPathFrontNil;
12431243

1244+
bindingset[tc, tail]
1245+
private Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) }
1246+
1247+
pragma[noinline]
1248+
private Content getHeadContent(Ap ap) { result = ap.getHead().getContent() }
1249+
12441250
class ApOption = AccessPathFrontOption;
12451251

12461252
ApOption apNone() { result = TAccessPathFrontNone() }
@@ -1301,15 +1307,15 @@ private module Stage3 {
13011307
)
13021308
or
13031309
// store
1304-
exists(TypedContent tc |
1305-
fwdFlowStore(node, tc, _, cc, argAp, config) and
1306-
ap.headUsesContent(tc)
1310+
exists(TypedContent tc, Ap ap0 |
1311+
fwdFlowStore(node, tc, ap0, cc, argAp, config) and
1312+
ap = apCons(tc, ap0)
13071313
)
13081314
or
13091315
// read
1310-
exists(TypedContent tc |
1311-
fwdFlowRead(tc, node, cc, argAp, config) and
1312-
fwdFlowConsCand(tc, ap, config) and
1316+
exists(Ap ap0, Content c |
1317+
fwdFlowRead(ap0, c, _, node, cc, argAp, config) and
1318+
fwdFlowConsCand(ap0, c, ap, config) and
13131319
Stage2::revFlow(node, _, _, unbindBool(ap.toBoolNonEmpty()), unbind(config))
13141320
)
13151321
or
@@ -1346,25 +1352,21 @@ private module Stage3 {
13461352
}
13471353

13481354
pragma[nomagic]
1349-
private predicate fwdFlowConsCand(TypedContent tc, Ap ap, Configuration config) {
1350-
fwdFlowStore(_, tc, ap, _, _, config)
1355+
private predicate fwdFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
1356+
exists(TypedContent tc |
1357+
fwdFlowStore(_, tc, tail, _, _, config) and
1358+
tc.getContent() = c and
1359+
cons = apCons(tc, tail)
1360+
)
13511361
}
13521362

13531363
pragma[nomagic]
1354-
private predicate fwdFlowRead0(
1355-
Node node1, TypedContent tc, Content c, Node node2, Cc cc, ApOption argAp,
1356-
AccessPathFrontHead ap, Configuration config
1364+
private predicate fwdFlowRead(
1365+
Ap ap, Content c, Node node1, Node node2, Cc cc, ApOption argAp, Configuration config
13571366
) {
13581367
fwdFlow(node1, cc, argAp, ap, config) and
13591368
readCand2(node1, c, node2, config) and
1360-
ap.headUsesContent(tc)
1361-
}
1362-
1363-
pragma[nomagic]
1364-
private predicate fwdFlowRead(
1365-
TypedContent tc, Node node, Cc cc, ApOption argAp, Configuration config
1366-
) {
1367-
fwdFlowRead0(_, tc, tc.getContent(), node, cc, argAp, _, config)
1369+
getHeadContent(ap) = c
13681370
}
13691371

13701372
pragma[nomagic]
@@ -1411,6 +1413,11 @@ private module Stage3 {
14111413
)
14121414
}
14131415

1416+
private predicate readStepFwd(Node n1, Ap ap1, Content c, Node n2, Ap ap2, Configuration config) {
1417+
fwdFlowRead(ap1, c, n1, n2, _, _, config) and
1418+
fwdFlowConsCand(ap1, c, ap2, config)
1419+
}
1420+
14141421
/**
14151422
* Holds if `node` with access path front `ap` is part of a path from a
14161423
* source to a sink in the configuration `config`.
@@ -1464,15 +1471,15 @@ private module Stage3 {
14641471
)
14651472
or
14661473
// store
1467-
exists(TypedContent tc |
1468-
revFlowStore(node, tc, ap, toReturn, returnAp, config) and
1469-
revFlowConsCand(tc, ap, config)
1474+
exists(Ap ap0, Content c |
1475+
revFlowStore(ap0, c, node, ap, toReturn, returnAp, config) and
1476+
revFlowConsCand(ap0, c, ap, config)
14701477
)
14711478
or
14721479
// read
1473-
exists(TypedContent tc, Ap ap0 |
1474-
revFlowRead(node, tc, ap, toReturn, returnAp, ap0, config) and
1475-
fwdFlowConsCand(tc, ap0, config)
1480+
exists(Node mid, Ap ap0 |
1481+
revFlow(mid, toReturn, returnAp, ap0, config) and
1482+
readStepFwd(node, ap, _, mid, ap0, config)
14761483
)
14771484
or
14781485
// flow into a callable
@@ -1494,35 +1501,29 @@ private module Stage3 {
14941501

14951502
pragma[nomagic]
14961503
predicate readCandFwd(Node node1, TypedContent tc, Ap ap, Node node2, Configuration config) {
1497-
fwdFlowRead0(node1, tc, tc.getContent(), node2, _, _, ap, config)
1498-
}
1499-
1500-
pragma[nomagic]
1501-
private predicate revFlowRead(
1502-
Node node, TypedContent tc, Ap ap, boolean toReturn, ApOption returnAp, Ap apf0,
1503-
Configuration config
1504-
) {
1505-
exists(Node mid |
1506-
readCandFwd(node, tc, ap, mid, config) and
1507-
revFlow(mid, toReturn, returnAp, apf0, config)
1508-
)
1504+
fwdFlowRead(ap, _, node1, node2, _, _, config) and
1505+
ap.headUsesContent(tc)
15091506
}
15101507

15111508
pragma[nomagic]
15121509
private predicate revFlowStore(
1513-
Node node, TypedContent tc, Ap ap, boolean toReturn, ApOption returnAp, Configuration config
1510+
Ap ap0, Content c, Node node, Ap ap, boolean toReturn, ApOption returnAp, Configuration config
15141511
) {
1515-
exists(Node mid |
1512+
exists(Node mid, TypedContent tc |
15161513
fwdFlow(node, _, _, ap, config) and
15171514
storeCand2(node, tc, mid, _, unbind(config)) and
1518-
revFlow(mid, toReturn, returnAp, TFrontHead(tc), unbind(config))
1515+
revFlow(mid, toReturn, returnAp, ap0, unbind(config)) and
1516+
ap0 = TFrontHead(tc) and
1517+
tc.getContent() = c
15191518
)
15201519
}
15211520

15221521
pragma[nomagic]
1523-
predicate revFlowConsCand(TypedContent tc, Ap ap, Configuration config) {
1524-
fwdFlowConsCand(tc, ap, config) and
1525-
revFlowRead(_, tc, _, _, _, ap, config)
1522+
predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
1523+
exists(Node mid |
1524+
revFlow(mid, _, _, tail, config) and
1525+
readStepFwd(_, cons, c, mid, tail, config)
1526+
)
15261527
}
15271528

15281529
pragma[nomagic]
@@ -1573,6 +1574,13 @@ private module Stage3 {
15731574
/* End: Stage 3 logic. */
15741575
}
15751576

1577+
private predicate stage3consCand(TypedContent tc, AccessPathFront apf, Configuration config) {
1578+
exists(AccessPathFront apf0 |
1579+
Stage3::revFlowConsCand(apf0, _, apf, config) and
1580+
apf0.getHead() = tc
1581+
)
1582+
}
1583+
15761584
/**
15771585
* Holds if `argApf` is recorded as the summary context for flow reaching `node`
15781586
* and remains relevant for the following pruning stage.
@@ -1590,7 +1598,7 @@ private predicate flowCandSummaryCtx(Node node, AccessPathFront argApf, Configur
15901598
*/
15911599
private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) {
15921600
exists(int tails, int nodes, int apLimit, int tupleLimit |
1593-
tails = strictcount(AccessPathFront apf | Stage3::revFlowConsCand(tc, apf, config)) and
1601+
tails = strictcount(AccessPathFront apf | stage3consCand(tc, apf, config)) and
15941602
nodes =
15951603
strictcount(Node n |
15961604
Stage3::revFlow(n, _, _, any(AccessPathFrontHead apf | apf.headUsesContent(tc)), config)
@@ -1606,11 +1614,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
16061614
private newtype TAccessPathApprox =
16071615
TNil(DataFlowType t) or
16081616
TConsNil(TypedContent tc, DataFlowType t) {
1609-
Stage3::revFlowConsCand(tc, TFrontNil(t), _) and
1617+
stage3consCand(tc, TFrontNil(t), _) and
16101618
not expensiveLen2unfolding(tc, _)
16111619
} or
16121620
TConsCons(TypedContent tc1, TypedContent tc2, int len) {
1613-
Stage3::revFlowConsCand(tc1, TFrontHead(tc2), _) and
1621+
stage3consCand(tc1, TFrontHead(tc2), _) and
16141622
len in [2 .. accessPathLimit()] and
16151623
not expensiveLen2unfolding(tc1, _)
16161624
} or
@@ -1740,7 +1748,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 {
17401748
override AccessPathApprox pop(TypedContent head) {
17411749
head = tc and
17421750
(
1743-
exists(TypedContent tc2 | Stage3::revFlowConsCand(tc, TFrontHead(tc2), _) |
1751+
exists(TypedContent tc2 | stage3consCand(tc, TFrontHead(tc2), _) |
17441752
result = TConsCons(tc2, _, len - 1)
17451753
or
17461754
len = 2 and
@@ -1751,7 +1759,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 {
17511759
or
17521760
exists(DataFlowType t |
17531761
len = 1 and
1754-
Stage3::revFlowConsCand(tc, TFrontNil(t), _) and
1762+
stage3consCand(tc, TFrontNil(t), _) and
17551763
result = TNil(t)
17561764
)
17571765
)
@@ -1914,7 +1922,7 @@ private module Stage4 {
19141922
) {
19151923
exists(AccessPathFront apf |
19161924
storeCand(mid, tc, node, apf0, apf, config) and
1917-
Stage3::revFlowConsCand(tc, apf0, config) and
1925+
stage3consCand(tc, apf0, config) and
19181926
Stage3::revFlow(node, _, _, apf, unbind(config))
19191927
)
19201928
}
@@ -1934,7 +1942,7 @@ private module Stage4 {
19341942
exists(Node mid, TypedContent tc |
19351943
fwdFlowRead0(mid, tc, ap0, node, cc, argAp, config) and
19361944
Stage3::revFlow(node, _, _, apf, unbind(config)) and
1937-
Stage3::revFlowConsCand(tc, apf, unbind(config))
1945+
stage3consCand(tc, apf, unbind(config))
19381946
)
19391947
}
19401948

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,9 @@ abstract class AccessPathFront extends TAccessPathFront {
802802

803803
abstract boolean toBoolNonEmpty();
804804

805+
TypedContent getHead() { this = TFrontHead(result) }
806+
807+
// TODO: delete
805808
predicate headUsesContent(TypedContent tc) { this = TFrontHead(tc) }
806809

807810
predicate isClearedAt(Node n) {

0 commit comments

Comments
 (0)