Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 48 additions & 20 deletions shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

class ApNil extends Ap;

predicate apTracksLength();

bindingset[result, ap]
ApApprox getApprox(Ap ap);

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

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

pragma[nomagic]
private int getAnApLengthLowerBoundRev(Ap ap) {
not apTracksLength() and // no need if we are tracking precise length information
accessPathLimit() > 1 and // `accessPathLimit() <= 1` is already checked in stages 1 and 2
ap instanceof ApNil and
result = 0
Expand Down Expand Up @@ -1388,7 +1392,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
exists(Nd mid, Ap ap0 |
revFlow(mid, returnCtx, returnAp, ap0) and
readStepFwd(node, ap, _, mid, ap0) and
if accessPathLimit() > 1
if accessPathLimit() > 1 and not apTracksLength()
then getAnApLengthLowerBoundRev(ap0) < accessPathLimit()
else any()
)
Expand Down Expand Up @@ -2776,6 +2780,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
ApNil() { this = false }
}

predicate apTracksLength() { none() }

bindingset[result, ap]
PrevStage::Ap getApprox(Ap ap) { any() }

Expand Down Expand Up @@ -2854,17 +2860,26 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

class ApNil = ApproxAccessPathFrontNil;

predicate apTracksLength() { any() }

PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() }

Typ getTyp(Type t) { any() }

bindingset[c, tail]
Ap apCons(Content c, Ap tail) { result.getAHead() = c and exists(tail) }
Ap apCons(Content c, Ap tail) {
exists(int length | result.getAHead(length) = c |
length = 1 and
tail instanceof ApNil
or
tail = TApproxFrontHead(_, length - 1)
)
}

class ApHeadContent = ContentApprox;

pragma[noinline]
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead() }
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead(_) }

predicate projectToHeadContent = getContentApproxCached/1;

Expand Down Expand Up @@ -2910,7 +2925,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
PrevStage::revFlow(node) and
PrevStage::readStepCand(_, c, _) and
Stage1::expectsContentEx(node, c) and
c = ap.getAHead()
c = ap.getAHead(_)
)
}

Expand Down Expand Up @@ -2956,17 +2971,26 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

class ApNil = AccessPathFrontNil;

predicate apTracksLength() { any() }

PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() }

Typ getTyp(Type t) { any() }

bindingset[c, tail]
Ap apCons(Content c, Ap tail) { result.getHead() = c and exists(tail) }
Ap apCons(Content c, Ap tail) {
exists(int length | result.getHead(length) = c |
length = 1 and
tail instanceof ApNil
or
tail = TFrontHead(_, length - 1)
)
}

class ApHeadContent = Content;

pragma[noinline]
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead() }
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead(_) }

ApHeadContent projectToHeadContent(Content c) { result = c }

Expand Down Expand Up @@ -3012,19 +3036,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
// When `node` is the target of a store, we interpret `clearsContent` as
// only pertaining to _earlier_ store steps. In this case, we need to postpone
// checking `clearsContent` to the step creation.
clearContent(node, ap.getHead(), false)
clearContent(node, ap.getHead(_), false)
}

pragma[nomagic]
private predicate clearExceptStore(Nd node, Ap ap) { clearContent(node, ap.getHead(), true) }
private predicate clearExceptStore(Nd node, Ap ap) { clearContent(node, ap.getHead(_), true) }

pragma[nomagic]
private predicate expectsContentCand(Nd node, Ap ap) {
exists(Content c |
PrevStage::revFlow(node) and
PrevStage::readStepCand(_, c, _) and
Stage1::expectsContentEx(node, c) and
c = ap.getHead()
c = ap.getHead(_)
)
}

Expand Down Expand Up @@ -3059,9 +3083,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
tails = strictcount(AccessPathFront apf | Stage4::consCand(c, apf)) and
nodes =
strictcount(Nd n |
Stage4::revFlow(n, any(AccessPathFrontHead apf | apf.getHead() = c))
Stage4::revFlow(n, any(AccessPathFrontHead apf | apf.getHead(_) = c))
or
Stage4::nodeMayUseSummary(n, any(AccessPathFrontHead apf | apf.getHead() = c))
Stage4::nodeMayUseSummary(n, any(AccessPathFrontHead apf | apf.getHead(_) = c))
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
Expand All @@ -3077,7 +3101,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
not expensiveLen2unfolding(c)
} or
TConsCons(Content c1, Content c2, int len) {
Stage4::consCand(c1, TFrontHead(c2)) and
Stage4::consCand(c1, TFrontHead(c2, _)) and
len in [2 .. Config::accessPathLimit()] and
not expensiveLen2unfolding(c1)
} or
Expand Down Expand Up @@ -3131,7 +3155,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

override int len() { result = 1 }

override AccessPathFront getFront() { result = TFrontHead(c) }
override AccessPathFront getFront() { result = TFrontHead(c, 1) }

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

override int len() { result = len }

override AccessPathFront getFront() { result = TFrontHead(c1) }
override AccessPathFront getFront() { result = TFrontHead(c1, len) }

override predicate isCons(Content head, AccessPathApprox tail) {
head = c1 and
Expand Down Expand Up @@ -3184,12 +3208,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

override int len() { result = len }

override AccessPathFront getFront() { result = TFrontHead(c) }
override AccessPathFront getFront() { result = TFrontHead(c, len) }

override predicate isCons(Content head, AccessPathApprox tail) {
head = c and
(
exists(Content c2 | Stage4::consCand(c, TFrontHead(c2)) |
exists(Content c2 | Stage4::consCand(c, TFrontHead(c2, len - 1)) |
tail = TConsCons(c2, _, len - 1)
or
len = 2 and
Expand Down Expand Up @@ -3226,6 +3250,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

class ApNil = AccessPathApproxNil;

predicate apTracksLength() { any() }

pragma[nomagic]
PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() }

Expand Down Expand Up @@ -3416,6 +3442,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

class ApNil = AccessPathNil;

predicate apTracksLength() { any() }

pragma[nomagic]
PrevStage::Ap getApprox(Ap ap) { result = ap.getApprox() }

Expand Down Expand Up @@ -3531,7 +3559,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {

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

override AccessPathFrontHead getFront() { result = TFrontHead(head_) }
override AccessPathFrontHead getFront() { result = TFrontHead(head_, this.length()) }

override AccessPathApproxCons getApprox() {
result = TConsNil(head_) and tail_ = TAccessPathNil()
Expand Down Expand Up @@ -3586,7 +3614,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
tail.length() = len - 1
}

override AccessPathFrontHead getFront() { result = TFrontHead(head1) }
override AccessPathFrontHead getFront() { result = TFrontHead(head1, len) }

override AccessPathApproxCons getApprox() {
result = TConsCons(head1, head2, len) or
Expand Down Expand Up @@ -3618,7 +3646,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
tail.length() = len - 1
}

override AccessPathFrontHead getFront() { result = TFrontHead(head_) }
override AccessPathFrontHead getFront() { result = TFrontHead(head_, len) }

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

Expand Down
27 changes: 12 additions & 15 deletions shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1797,12 +1797,12 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
cached
newtype TAccessPathFront =
TFrontNil() or
TFrontHead(Content c)
TFrontHead(Content c, int length) { length in [1 .. accessPathLimit()] }

cached
newtype TApproxAccessPathFront =
TApproxFrontNil() or
TApproxFrontHead(ContentApprox c)
TApproxFrontHead(ContentApprox c, int length) { length in [1 .. accessPathLimit()] }

cached
newtype TAccessPathFrontOption =
Expand Down Expand Up @@ -2505,15 +2505,10 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {

abstract boolean toBoolNonEmpty();

ContentApprox getHead() { this = TApproxFrontHead(result) }
ContentApprox getHead(int length) { this = TApproxFrontHead(result, length) }

pragma[nomagic]
Content getAHead() {
exists(ContentApprox cont |
this = TApproxFrontHead(cont) and
cont = getContentApproxCached(result)
)
}
Content getAHead(int length) { this.getHead(length) = getContentApproxCached(result) }
}

class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil {
Expand All @@ -2524,10 +2519,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {

class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead {
private ContentApprox c;
private int length;

ApproxAccessPathFrontHead() { this = TApproxFrontHead(c) }
ApproxAccessPathFrontHead() { this = TApproxFrontHead(c, length) }

override string toString() { result = c.toString() }
override string toString() { result = c + " (length: " + length + ")" }

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

abstract ApproxAccessPathFront toApprox();

Content getHead() { this = TFrontHead(result) }
Content getHead(int length) { this = TFrontHead(result, length) }
}

class AccessPathFrontNil extends AccessPathFront, TFrontNil {
Expand All @@ -2560,12 +2556,13 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {

class AccessPathFrontHead extends AccessPathFront, TFrontHead {
private Content c;
private int length;

AccessPathFrontHead() { this = TFrontHead(c) }
AccessPathFrontHead() { this = TFrontHead(c, length) }

override string toString() { result = c.toString() }
override string toString() { result = c + " (length: " + length + ")" }

override ApproxAccessPathFront toApprox() { result.getAHead() = c }
override ApproxAccessPathFront toApprox() { result.getAHead(length) = c }
}

/** An optional access path front. */
Expand Down
Loading