Skip to content

Commit 6eecb46

Browse files
committed
Data flow: Track access path lengths in stages 3 and 4
1 parent 5a879f2 commit 6eecb46

2 files changed

Lines changed: 45 additions & 44 deletions

File tree

shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
375375

376376
class ApNil extends Ap;
377377

378+
predicate apTracksLength();
379+
378380
bindingset[result, ap]
379381
ApApprox getApprox(Ap ap);
380382

@@ -563,6 +565,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
563565

564566
pragma[nomagic]
565567
private int getAnApLengthLowerBound(Ap ap) {
568+
not apTracksLength() and // no need if we are tracking precise length information
566569
accessPathLimit() > 1 and // `accessPathLimit() <= 1` is already checked in stages 1 and 2
567570
ap instanceof ApNil and
568571
result = 0
@@ -609,7 +612,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
609612
fwdFlowStore(_, _, ap0, _, c, t, stored, node, cc, summaryCtx) and
610613
ap = apCons(c, ap0) and
611614
apa = getApprox(ap) and
612-
if accessPathLimit() > 1
615+
if accessPathLimit() > 1 and not apTracksLength()
613616
then getAnApLengthLowerBound(ap0) < accessPathLimit()
614617
else any()
615618
)
@@ -1339,6 +1342,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
13391342

13401343
pragma[nomagic]
13411344
private int getAnApLengthLowerBoundRev(Ap ap) {
1345+
not apTracksLength() and // no need if we are tracking precise length information
13421346
accessPathLimit() > 1 and // `accessPathLimit() <= 1` is already checked in stages 1 and 2
13431347
ap instanceof ApNil and
13441348
result = 0
@@ -1388,7 +1392,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
13881392
exists(Nd mid, Ap ap0 |
13891393
revFlow(mid, returnCtx, returnAp, ap0) and
13901394
readStepFwd(node, ap, _, mid, ap0) and
1391-
if accessPathLimit() > 1
1395+
if accessPathLimit() > 1 and not apTracksLength()
13921396
then getAnApLengthLowerBoundRev(ap0) < accessPathLimit()
13931397
else any()
13941398
)
@@ -2776,6 +2780,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
27762780
ApNil() { this = false }
27772781
}
27782782

2783+
predicate apTracksLength() { none() }
2784+
27792785
bindingset[result, ap]
27802786
PrevStage::Ap getApprox(Ap ap) { any() }
27812787

@@ -2854,15 +2860,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
28542860

28552861
class ApNil = ApproxAccessPathFrontNil;
28562862

2863+
predicate apTracksLength() { any() }
2864+
28572865
PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
28582866

28592867
Typ getTyp(Type t) { any() }
28602868

28612869
bindingset[c, tail]
28622870
Ap apCons(Content c, Ap tail) {
2863-
exists(boolean isSingleton |
2864-
result.getAHead(isSingleton) = c and
2865-
if tail instanceof ApNil then isSingleton = true else isSingleton = false
2871+
exists(int length | result.getAHead(length) = c |
2872+
length = 1 and
2873+
tail instanceof ApNil
2874+
or
2875+
tail = TApproxFrontHead(_, length - 1)
28662876
)
28672877
}
28682878

@@ -2961,15 +2971,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29612971

29622972
class ApNil = AccessPathFrontNil;
29632973

2974+
predicate apTracksLength() { any() }
2975+
29642976
PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() }
29652977

29662978
Typ getTyp(Type t) { any() }
29672979

29682980
bindingset[c, tail]
29692981
Ap apCons(Content c, Ap tail) {
2970-
exists(boolean isSingleton |
2971-
result.getHead(isSingleton) = c and
2972-
if tail instanceof ApNil then isSingleton = true else isSingleton = false
2982+
exists(int length | result.getHead(length) = c |
2983+
length = 1 and
2984+
tail instanceof ApNil
2985+
or
2986+
tail = TFrontHead(_, length - 1)
29732987
)
29742988
}
29752989

@@ -3141,7 +3155,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
31413155

31423156
override int len() { result = 1 }
31433157

3144-
override AccessPathFront getFront() { result = TFrontHead(c, true) }
3158+
override AccessPathFront getFront() { result = TFrontHead(c, 1) }
31453159

31463160
override predicate isCons(Content head, AccessPathApprox tail) { head = c and tail = TNil() }
31473161
}
@@ -3163,7 +3177,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
31633177

31643178
override int len() { result = len }
31653179

3166-
override AccessPathFront getFront() { result = TFrontHead(c1, false) }
3180+
override AccessPathFront getFront() { result = TFrontHead(c1, len) }
31673181

31683182
override predicate isCons(Content head, AccessPathApprox tail) {
31693183
head = c1 and
@@ -3194,17 +3208,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
31943208

31953209
override int len() { result = len }
31963210

3197-
override AccessPathFront getFront() {
3198-
if len = 1 then result = TFrontHead(c, true) else result = TFrontHead(c, false)
3199-
}
3211+
override AccessPathFront getFront() { result = TFrontHead(c, len) }
32003212

32013213
override predicate isCons(Content head, AccessPathApprox tail) {
32023214
head = c and
32033215
(
3204-
exists(Content c2, boolean isSingleton |
3205-
Stage4::consCand(c, TFrontHead(c2, isSingleton)) and
3206-
if len > 2 then isSingleton = false else isSingleton = true
3207-
|
3216+
exists(Content c2 | Stage4::consCand(c, TFrontHead(c2, len - 1)) |
32083217
tail = TConsCons(c2, _, len - 1)
32093218
or
32103219
len = 2 and
@@ -3241,6 +3250,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
32413250

32423251
class ApNil = AccessPathApproxNil;
32433252

3253+
predicate apTracksLength() { any() }
3254+
32443255
pragma[nomagic]
32453256
PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() }
32463257

@@ -3431,6 +3442,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
34313442

34323443
class ApNil = AccessPathNil;
34333444

3445+
predicate apTracksLength() { any() }
3446+
34343447
pragma[nomagic]
34353448
PrevStage::Ap getApprox(Ap ap) { result = ap.getApprox() }
34363449

@@ -3546,11 +3559,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
35463559

35473560
override predicate isCons(Content head, AccessPath tail) { head = head_ and tail = tail_ }
35483561

3549-
override AccessPathFrontHead getFront() {
3550-
if this.length() = 1
3551-
then result = TFrontHead(head_, true)
3552-
else result = TFrontHead(head_, false)
3553-
}
3562+
override AccessPathFrontHead getFront() { result = TFrontHead(head_, this.length()) }
35543563

35553564
override AccessPathApproxCons getApprox() {
35563565
result = TConsNil(head_) and tail_ = TAccessPathNil()
@@ -3605,7 +3614,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
36053614
tail.length() = len - 1
36063615
}
36073616

3608-
override AccessPathFrontHead getFront() { result = TFrontHead(head1, false) }
3617+
override AccessPathFrontHead getFront() { result = TFrontHead(head1, len) }
36093618

36103619
override AccessPathApproxCons getApprox() {
36113620
result = TConsCons(head1, head2, len) or
@@ -3637,9 +3646,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
36373646
tail.length() = len - 1
36383647
}
36393648

3640-
override AccessPathFrontHead getFront() {
3641-
if len = 1 then result = TFrontHead(head_, true) else result = TFrontHead(head_, false)
3642-
}
3649+
override AccessPathFrontHead getFront() { result = TFrontHead(head_, len) }
36433650

36443651
override AccessPathApproxCons getApprox() { result = TCons1(head_, len) }
36453652

shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,12 +1797,12 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
17971797
cached
17981798
newtype TAccessPathFront =
17991799
TFrontNil() or
1800-
TFrontHead(Content c, Boolean isSingleton)
1800+
TFrontHead(Content c, int length) { length in [1 .. accessPathLimit()] }
18011801

18021802
cached
18031803
newtype TApproxAccessPathFront =
18041804
TApproxFrontNil() or
1805-
TApproxFrontHead(ContentApprox c, Boolean isSingleton)
1805+
TApproxFrontHead(ContentApprox c, int length) { length in [1 .. accessPathLimit()] }
18061806

18071807
cached
18081808
newtype TAccessPathFrontOption =
@@ -2505,12 +2505,10 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
25052505

25062506
abstract boolean toBoolNonEmpty();
25072507

2508-
ContentApprox getHead(boolean isSingleton) { this = TApproxFrontHead(result, isSingleton) }
2508+
ContentApprox getHead(int length) { this = TApproxFrontHead(result, length) }
25092509

25102510
pragma[nomagic]
2511-
Content getAHead(boolean isSingleton) {
2512-
this.getHead(isSingleton) = getContentApproxCached(result)
2513-
}
2511+
Content getAHead(int length) { this.getHead(length) = getContentApproxCached(result) }
25142512
}
25152513

25162514
class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil {
@@ -2521,13 +2519,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
25212519

25222520
class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead {
25232521
private ContentApprox c;
2524-
private boolean isSingleton;
2522+
private int length;
25252523

2526-
ApproxAccessPathFrontHead() { this = TApproxFrontHead(c, isSingleton) }
2524+
ApproxAccessPathFrontHead() { this = TApproxFrontHead(c, length) }
25272525

2528-
override string toString() {
2529-
if isSingleton = true then result = c.toString() + " (singleton)" else result = c.toString()
2530-
}
2526+
override string toString() { result = c + " (length: " + length + ")" }
25312527

25322528
override boolean toBoolNonEmpty() { result = true }
25332529
}
@@ -2549,7 +2545,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
25492545

25502546
abstract ApproxAccessPathFront toApprox();
25512547

2552-
Content getHead(boolean isSingleton) { this = TFrontHead(result, isSingleton) }
2548+
Content getHead(int length) { this = TFrontHead(result, length) }
25532549
}
25542550

25552551
class AccessPathFrontNil extends AccessPathFront, TFrontNil {
@@ -2560,15 +2556,13 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
25602556

25612557
class AccessPathFrontHead extends AccessPathFront, TFrontHead {
25622558
private Content c;
2563-
private boolean isSingleton;
2559+
private int length;
25642560

2565-
AccessPathFrontHead() { this = TFrontHead(c, isSingleton) }
2561+
AccessPathFrontHead() { this = TFrontHead(c, length) }
25662562

2567-
override string toString() {
2568-
if isSingleton = true then result = c.toString() + " (singleton)" else result = c.toString()
2569-
}
2563+
override string toString() { result = c + " (length: " + length + ")" }
25702564

2571-
override ApproxAccessPathFront toApprox() { result.getAHead(isSingleton) = c }
2565+
override ApproxAccessPathFront toApprox() { result.getAHead(length) = c }
25722566
}
25732567

25742568
/** An optional access path front. */

0 commit comments

Comments
 (0)