Skip to content

Commit c79daf0

Browse files
committed
Dataflow: Duplicate accesspath type info of the tail in cons relations.
1 parent b84b1a4 commit c79daf0

File tree

1 file changed

+65
-61
lines changed

1 file changed

+65
-61
lines changed

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

Lines changed: 65 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,8 +1071,8 @@ module Impl<FullStateConfigSig Config> {
10711071

10721072
Typ getTyp(DataFlowType t);
10731073

1074-
bindingset[tc, tail]
1075-
Ap apCons(TypedContent tc, Ap tail);
1074+
bindingset[tc, t, tail]
1075+
Ap apCons(TypedContent tc, Typ t, Ap tail);
10761076

10771077
/**
10781078
* An approximation of `Content` that corresponds to the precision level of
@@ -1263,7 +1263,7 @@ module Impl<FullStateConfigSig Config> {
12631263
// store
12641264
exists(TypedContent tc, Typ t0, Ap ap0 |
12651265
fwdFlowStore(_, t0, ap0, tc, t, node, state, cc, summaryCtx, argAp) and
1266-
ap = apCons(tc, ap0) and
1266+
ap = apCons(tc, t0, ap0) and
12671267
apa = getApprox(ap)
12681268
)
12691269
or
@@ -1330,7 +1330,7 @@ module Impl<FullStateConfigSig Config> {
13301330
exists(TypedContent tc |
13311331
fwdFlowStore(_, t1, tail, tc, t2, _, _, _, _, _) and
13321332
tc.getContent() = c and
1333-
cons = apCons(tc, tail)
1333+
cons = apCons(tc, t1, tail)
13341334
)
13351335
}
13361336

@@ -1423,9 +1423,9 @@ module Impl<FullStateConfigSig Config> {
14231423
}
14241424

14251425
pragma[nomagic]
1426-
private predicate storeStepFwd(NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2) {
1427-
fwdFlowStore(node1, _, ap1, tc, _, node2, _, _, _, _) and
1428-
ap2 = apCons(tc, ap1) and
1426+
private predicate storeStepFwd(NodeEx node1, Typ t1, Ap ap1, TypedContent tc, NodeEx node2, Ap ap2) {
1427+
fwdFlowStore(node1, t1, ap1, tc, _, node2, _, _, _, _) and
1428+
ap2 = apCons(tc, t1, ap1) and
14291429
readStepFwd(_, ap2, tc.getContent(), _, _)
14301430
}
14311431

@@ -1563,7 +1563,7 @@ module Impl<FullStateConfigSig Config> {
15631563
or
15641564
// store
15651565
exists(Ap ap0, Content c |
1566-
revFlowStore(ap0, c, ap, node, state, _, _, returnCtx, returnAp) and
1566+
revFlowStore(ap0, c, ap, _, node, state, _, _, returnCtx, returnAp) and
15671567
revFlowConsCand(ap0, c, ap)
15681568
)
15691569
or
@@ -1602,11 +1602,11 @@ module Impl<FullStateConfigSig Config> {
16021602

16031603
pragma[nomagic]
16041604
private predicate revFlowStore(
1605-
Ap ap0, Content c, Ap ap, NodeEx node, FlowState state, TypedContent tc, NodeEx mid,
1605+
Ap ap0, Content c, Ap ap, Typ t, NodeEx node, FlowState state, TypedContent tc, NodeEx mid,
16061606
ReturnCtx returnCtx, ApOption returnAp
16071607
) {
16081608
revFlow(mid, state, returnCtx, returnAp, ap0) and
1609-
storeStepFwd(node, ap, tc, mid, ap0) and
1609+
storeStepFwd(node, t, ap, tc, mid, ap0) and
16101610
tc.getContent() = c
16111611
}
16121612

@@ -1676,7 +1676,7 @@ module Impl<FullStateConfigSig Config> {
16761676
) {
16771677
exists(Ap ap2 |
16781678
PrevStage::storeStepCand(node1, _, tc, c, node2, contentType, containerType) and
1679-
revFlowStore(ap2, c, ap1, node1, _, tc, node2, _, _) and
1679+
revFlowStore(ap2, c, ap1, _, node1, _, tc, node2, _, _) and
16801680
revFlowConsCand(ap2, c, ap1)
16811681
)
16821682
}
@@ -1685,7 +1685,7 @@ module Impl<FullStateConfigSig Config> {
16851685
exists(Ap ap1, Ap ap2 |
16861686
revFlow(node2, _, _, _, pragma[only_bind_into](ap2)) and
16871687
readStepFwd(node1, ap1, c, node2, ap2) and
1688-
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _)
1688+
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _, _, _)
16891689
)
16901690
}
16911691

@@ -1699,21 +1699,26 @@ module Impl<FullStateConfigSig Config> {
16991699
pragma[nomagic]
17001700
predicate revFlowAp(NodeEx node, Ap ap) { revFlow(node, _, _, _, ap) }
17011701

1702-
private predicate fwdConsCand(TypedContent tc, Ap ap) { storeStepFwd(_, ap, tc, _, _) }
1702+
private predicate fwdConsCand(TypedContent tc, Typ t, Ap ap) { storeStepFwd(_, t, ap, tc, _, _) }
17031703

1704-
private predicate revConsCand(TypedContent tc, Ap ap) { storeStepCand(_, ap, tc, _, _, _, _) }
1704+
private predicate revConsCand(TypedContent tc, Typ t, Ap ap) {
1705+
exists(Ap ap2, Content c |
1706+
revFlowStore(ap2, c, ap, t, _, _, tc, _, _, _) and
1707+
revFlowConsCand(ap2, c, ap)
1708+
)
1709+
}
17051710

17061711
private predicate validAp(Ap ap) {
17071712
revFlow(_, _, _, _, ap) and ap instanceof ApNil
17081713
or
1709-
exists(TypedContent head, Ap tail |
1710-
consCand(head, tail) and
1711-
ap = apCons(head, tail)
1714+
exists(TypedContent head, Typ t, Ap tail |
1715+
consCand(head, t, tail) and
1716+
ap = apCons(head, t, tail)
17121717
)
17131718
}
17141719

1715-
additional predicate consCand(TypedContent tc, Ap ap) {
1716-
revConsCand(tc, ap) and
1720+
additional predicate consCand(TypedContent tc, Typ t, Ap ap) {
1721+
revConsCand(tc, t, ap) and
17171722
validAp(ap)
17181723
}
17191724

@@ -1766,8 +1771,8 @@ module Impl<FullStateConfigSig Config> {
17661771
) {
17671772
fwd = true and
17681773
nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _)) and
1769-
fields = count(TypedContent f0 | fwdConsCand(f0, _)) and
1770-
conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap)) and
1774+
fields = count(TypedContent f0 | fwdConsCand(f0, _, _)) and
1775+
conscand = count(TypedContent f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and
17711776
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _)) and
17721777
tuples =
17731778
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Typ t, Ap ap |
@@ -1776,8 +1781,8 @@ module Impl<FullStateConfigSig Config> {
17761781
or
17771782
fwd = false and
17781783
nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and
1779-
fields = count(TypedContent f0 | consCand(f0, _)) and
1780-
conscand = count(TypedContent f0, Ap ap | consCand(f0, ap)) and
1784+
fields = count(TypedContent f0 | consCand(f0, _, _)) and
1785+
conscand = count(TypedContent f0, Typ t, Ap ap | consCand(f0, t, ap)) and
17811786
states = count(FlowState state | revFlow(_, state, _, _, _)) and
17821787
tuples =
17831788
count(NodeEx n, FlowState state, ReturnCtx returnCtx, ApOption retAp, Ap ap |
@@ -1895,8 +1900,8 @@ module Impl<FullStateConfigSig Config> {
18951900

18961901
Typ getTyp(DataFlowType t) { any() }
18971902

1898-
bindingset[tc, tail]
1899-
Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) }
1903+
bindingset[tc, t, tail]
1904+
Ap apCons(TypedContent tc, Typ t, Ap tail) { result = true and exists(tc) and exists(t) and exists(tail) }
19001905

19011906
class ApHeadContent = Unit;
19021907

@@ -2165,8 +2170,8 @@ module Impl<FullStateConfigSig Config> {
21652170

21662171
Typ getTyp(DataFlowType t) { result = t }
21672172

2168-
bindingset[tc, tail]
2169-
Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) }
2173+
bindingset[tc, t, tail]
2174+
Ap apCons(TypedContent tc, Typ t, Ap tail) { result.getAHead() = tc and exists(t) and exists(tail) }
21702175

21712176
class ApHeadContent = ContentApprox;
21722177

@@ -2249,8 +2254,8 @@ module Impl<FullStateConfigSig Config> {
22492254

22502255
Typ getTyp(DataFlowType t) { result = t }
22512256

2252-
bindingset[tc, tail]
2253-
Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) }
2257+
bindingset[tc, t, tail]
2258+
Ap apCons(TypedContent tc, Typ t, Ap tail) { result.getHead() = tc and exists(t) and exists(tail) }
22542259

22552260
class ApHeadContent = Content;
22562261

@@ -2373,7 +2378,7 @@ module Impl<FullStateConfigSig Config> {
23732378
*/
23742379
private predicate expensiveLen2unfolding(TypedContent tc) {
23752380
exists(int tails, int nodes, int apLimit, int tupleLimit |
2376-
tails = strictcount(AccessPathFront apf | Stage4::consCand(tc, apf)) and
2381+
tails = strictcount(DataFlowType t, AccessPathFront apf | Stage4::consCand(tc, t, apf)) and
23772382
nodes =
23782383
strictcount(NodeEx n, FlowState state |
23792384
Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = tc))
@@ -2390,11 +2395,11 @@ module Impl<FullStateConfigSig Config> {
23902395
private newtype TAccessPathApprox =
23912396
TNil(DataFlowType t) or
23922397
TConsNil(TypedContent tc, DataFlowType t) {
2393-
Stage4::consCand(tc, TFrontNil(t)) and
2398+
Stage4::consCand(tc, t, TFrontNil(t)) and
23942399
not expensiveLen2unfolding(tc)
23952400
} or
23962401
TConsCons(TypedContent tc1, TypedContent tc2, int len) {
2397-
Stage4::consCand(tc1, TFrontHead(tc2)) and
2402+
Stage4::consCand(tc1, _, TFrontHead(tc2)) and
23982403
len in [2 .. accessPathLimit()] and
23992404
not expensiveLen2unfolding(tc1)
24002405
} or
@@ -2421,8 +2426,8 @@ module Impl<FullStateConfigSig Config> {
24212426

24222427
abstract AccessPathFront getFront();
24232428

2424-
/** Gets the access path obtained by popping `head` from this path, if any. */
2425-
abstract AccessPathApprox pop(TypedContent head);
2429+
/** Holds if this is a representation of `head` followed by the `typ,tail` pair. */
2430+
abstract predicate isCons(TypedContent head, DataFlowType typ, AccessPathApprox tail);
24262431
}
24272432

24282433
private class AccessPathApproxNil extends AccessPathApprox, TNil {
@@ -2440,7 +2445,7 @@ module Impl<FullStateConfigSig Config> {
24402445

24412446
override AccessPathFront getFront() { result = TFrontNil(t) }
24422447

2443-
override AccessPathApprox pop(TypedContent head) { none() }
2448+
override predicate isCons(TypedContent head, DataFlowType typ, AccessPathApprox tail) { none() }
24442449
}
24452450

24462451
abstract private class AccessPathApproxCons extends AccessPathApprox { }
@@ -2464,7 +2469,7 @@ module Impl<FullStateConfigSig Config> {
24642469

24652470
override AccessPathFront getFront() { result = TFrontHead(tc) }
24662471

2467-
override AccessPathApprox pop(TypedContent head) { head = tc and result = TNil(t) }
2472+
override predicate isCons(TypedContent head, DataFlowType typ, AccessPathApprox tail) { head = tc and typ = t and tail = TNil(t) }
24682473
}
24692474

24702475
private class AccessPathApproxConsCons extends AccessPathApproxCons, TConsCons {
@@ -2488,15 +2493,16 @@ module Impl<FullStateConfigSig Config> {
24882493

24892494
override AccessPathFront getFront() { result = TFrontHead(tc1) }
24902495

2491-
override AccessPathApprox pop(TypedContent head) {
2496+
override predicate isCons(TypedContent head, DataFlowType typ, AccessPathApprox tail) {
24922497
head = tc1 and
2498+
typ = tc2.getContainerType() and
24932499
(
2494-
result = TConsCons(tc2, _, len - 1)
2500+
tail = TConsCons(tc2, _, len - 1)
24952501
or
24962502
len = 2 and
2497-
result = TConsNil(tc2, _)
2503+
tail = TConsNil(tc2, _)
24982504
or
2499-
result = TCons1(tc2, len - 1)
2505+
tail = TCons1(tc2, len - 1)
25002506
)
25012507
}
25022508
}
@@ -2521,32 +2527,30 @@ module Impl<FullStateConfigSig Config> {
25212527

25222528
override AccessPathFront getFront() { result = TFrontHead(tc) }
25232529

2524-
override AccessPathApprox pop(TypedContent head) {
2530+
override predicate isCons(TypedContent head, DataFlowType typ, AccessPathApprox tail) {
25252531
head = tc and
25262532
(
2527-
exists(TypedContent tc2 | Stage4::consCand(tc, TFrontHead(tc2)) |
2528-
result = TConsCons(tc2, _, len - 1)
2533+
exists(TypedContent tc2 | Stage4::consCand(tc, typ, TFrontHead(tc2)) |
2534+
tail = TConsCons(tc2, _, len - 1)
25292535
or
25302536
len = 2 and
2531-
result = TConsNil(tc2, _)
2537+
tail = TConsNil(tc2, _)
25322538
or
2533-
result = TCons1(tc2, len - 1)
2539+
tail = TCons1(tc2, len - 1)
25342540
)
25352541
or
25362542
exists(DataFlowType t |
25372543
len = 1 and
2538-
Stage4::consCand(tc, TFrontNil(t)) and
2539-
result = TNil(t)
2544+
Stage4::consCand(tc, t, TFrontNil(t)) and
2545+
typ = t and
2546+
tail = TNil(t)
25402547
)
25412548
)
25422549
}
25432550
}
25442551

2545-
/** Gets the access path obtained by popping `tc` from `ap`, if any. */
2546-
private AccessPathApprox pop(TypedContent tc, AccessPathApprox apa) { result = apa.pop(tc) }
2547-
2548-
/** Gets the access path obtained by pushing `tc` onto `ap`. */
2549-
private AccessPathApprox push(TypedContent tc, AccessPathApprox apa) { apa = pop(tc, result) }
2552+
/** Gets the access path obtained by pushing `tc` onto the `t,apa` pair. */
2553+
private AccessPathApprox push(TypedContent tc, DataFlowType t, AccessPathApprox apa) { result.isCons(tc, t, apa) }
25502554

25512555
private newtype TAccessPathApproxOption =
25522556
TAccessPathApproxNone() or
@@ -2578,8 +2582,8 @@ module Impl<FullStateConfigSig Config> {
25782582

25792583
Typ getTyp(DataFlowType t) { result = t }
25802584

2581-
bindingset[tc, tail]
2582-
Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) }
2585+
bindingset[tc, t, tail]
2586+
Ap apCons(TypedContent tc, Typ t, Ap tail) { result = push(tc, t, tail) }
25832587

25842588
class ApHeadContent = Content;
25852589

@@ -2710,8 +2714,8 @@ module Impl<FullStateConfigSig Config> {
27102714
tc = apa.getHead() and
27112715
len = apa.len() and
27122716
result =
2713-
strictcount(AccessPathFront apf |
2714-
Stage5::consCand(tc, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1))
2717+
strictcount(DataFlowType t, AccessPathFront apf |
2718+
Stage5::consCand(tc, t, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1))
27152719
)
27162720
)
27172721
}
@@ -2738,9 +2742,9 @@ module Impl<FullStateConfigSig Config> {
27382742
}
27392743

27402744
private AccessPathApprox getATail(AccessPathApprox apa) {
2741-
exists(TypedContent head |
2742-
apa.pop(head) = result and
2743-
Stage5::consCand(head, result)
2745+
exists(TypedContent head, DataFlowType t |
2746+
apa.isCons(head, t, result) and
2747+
Stage5::consCand(head, t, result)
27442748
)
27452749
}
27462750

@@ -2962,7 +2966,7 @@ module Impl<FullStateConfigSig Config> {
29622966
override TypedContent getHead() { result = head1 }
29632967

29642968
override AccessPath getTail() {
2965-
Stage5::consCand(head1, result.getApprox()) and
2969+
Stage5::consCand(head1, head2.getContainerType(), result.getApprox()) and
29662970
result.getHead() = head2 and
29672971
result.length() = len - 1
29682972
}
@@ -2994,7 +2998,7 @@ module Impl<FullStateConfigSig Config> {
29942998
override TypedContent getHead() { result = head }
29952999

29963000
override AccessPath getTail() {
2997-
Stage5::consCand(head, result.getApprox()) and result.length() = len - 1
3001+
Stage5::consCand(head, _, result.getApprox()) and result.length() = len - 1
29983002
}
29993003

30003004
override AccessPathFrontHead getFront() { result = TFrontHead(head) }

0 commit comments

Comments
 (0)