C#/C++/Java: Unbreak partial data flow support

Partial data flow had a semantic merge conflict with this branch. The
problem is that partial data flow doesn't (and shouldn't) cause the
initial pruning steps to run, but the length-2 access paths depend on
the `consCand` information that comes from that initial pruning. The
solution is to restore the old `AccessPath` class, now called
`PartialAccessPath` for use only by partial data flow.

With this change, partial data flow will in some cases allow more field
flow than non-partial data flow.
This commit is contained in:
Jonas Jensen
2019-09-02 13:54:56 +02:00
parent dec0c3a0ee
commit c3bc9f8575
20 changed files with 1682 additions and 589 deletions

View File

@@ -2048,11 +2048,64 @@ private module FlowExploration {
result = distSrcExt(TCallable(c, config)) - 1
}
private newtype TPartialAccessPath =
TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
* Conceptually a list of `Content`s followed by a `Type`, but only the first
* element of the list and its length are tracked. If data flows from a source to
* a given node with a given `AccessPath`, this indicates the sequence of
* dereference operations needed to get from the value in the node to the
* tracked object. The final type indicates the type of the tracked object.
*/
private class PartialAccessPath extends TPartialAccessPath {
abstract string toString();
Content getHead() { this = TPartialCons(result, _) }
int len() {
this = TPartialNil(_) and result = 0
or
this = TPartialCons(_, result)
}
DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
}
abstract AccessPathFront getFront();
}
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
exists(DataFlowType t | this = TPartialNil(t) | result = ppReprType(t))
}
override AccessPathFront getFront() {
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
private class PartialAccessPathCons extends PartialAccessPath, TPartialCons {
override string toString() {
exists(Content f, int len | this = TPartialCons(f, len) |
result = f.toString() + ", ... (" + len.toString() + ")"
)
}
override AccessPathFront getFront() {
exists(Content f | this = TPartialCons(f, _) | result = TFrontHead(f))
}
}
private newtype TPartialPathNode =
TPartialPathNodeMk(Node node, CallContext cc, AccessPath ap, Configuration config) {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedRepr(node.getType())) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathNodeMk0(
Node node, CallContext cc, AccessPath ap, Configuration config
Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
CallContext cc;
AccessPath ap;
PartialAccessPath ap;
Configuration config;
@@ -2148,7 +2201,7 @@ private module FlowExploration {
CallContext getCallContext() { result = cc }
AccessPath getAp() { result = ap }
PartialAccessPath getAp() { result = ap }
override Configuration getConfiguration() { result = config }
@@ -2161,7 +2214,7 @@ private module FlowExploration {
}
private predicate partialPathStep(
PartialPathNodePriv mid, Node node, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
or
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
jumpStep(mid.getNode(), node, config) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
or
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
cc = mid.getCallContext() and
config = mid.getConfiguration()
or
exists(AccessPath ap0, Content f |
exists(PartialAccessPath ap0, Content f |
partialPathReadStep(mid, ap0, f, node, cc, config) and
apConsFwd(ap, f, ap0, config)
)
@@ -2210,7 +2263,7 @@ private module FlowExploration {
pragma[inline]
private predicate partialPathStoreStep(
PartialPathNodePriv mid, AccessPath ap1, Content f, Node node, AccessPath ap2
PartialPathNodePriv mid, PartialAccessPath ap1, Content f, Node node, PartialAccessPath ap2
) {
ap1 = mid.getAp() and
store(mid.getNode(), f, node) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
}
pragma[nomagic]
private predicate apConsFwd(AccessPath ap1, Content f, AccessPath ap2, Configuration config) {
private predicate apConsFwd(
PartialAccessPath ap1, Content f, PartialAccessPath ap2, Configuration config
) {
exists(PartialPathNodePriv mid |
partialPathStoreStep(mid, ap1, f, _, ap2) and
config = mid.getConfiguration()
@@ -2229,7 +2284,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathReadStep(
PartialPathNodePriv mid, AccessPath ap, Content f, Node node, CallContext cc,
PartialPathNodePriv mid, PartialAccessPath ap, Content f, Node node, CallContext cc,
Configuration config
) {
ap = mid.getAp() and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable0(
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, AccessPath ap,
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap,
Configuration config
) {
pos = getReturnPosition(mid.getNode()) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathOutOfCallable1(
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc |
partialPathOutOfCallable0(mid, pos, innercc, ap, config) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(ReturnKind kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, cc, ap, config)
@@ -2276,7 +2331,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfArgument(
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, AccessPath ap,
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, PartialAccessPath ap,
Configuration config
) {
exists(
@@ -2302,7 +2357,7 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodePriv mid, int i, CallContext cc, DataFlowCall call, boolean emptyAp,
AccessPath ap, Configuration config
PartialAccessPath ap, Configuration config
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
@@ -2311,16 +2366,16 @@ private module FlowExploration {
ap = mid.getAp() and
config = mid.getConfiguration()
|
ap instanceof AccessPathNil and emptyAp = true
ap instanceof PartialAccessPathNil and emptyAp = true
or
ap instanceof AccessPathCons and emptyAp = false
ap instanceof PartialAccessPathCons and emptyAp = false
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodePriv mid, DataFlowCallable callable, int i, CallContext outercc,
DataFlowCall call, boolean emptyAp, AccessPath ap, Configuration config
DataFlowCall call, boolean emptyAp, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, emptyAp, ap, config) and
callable = resolveCall(call, outercc)
@@ -2328,7 +2383,7 @@ private module FlowExploration {
private predicate partialPathIntoCallable(
PartialPathNodePriv mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
DataFlowCall call, AccessPath ap, Configuration config
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
exists(int i, DataFlowCallable callable, boolean emptyAp |
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
pragma[nomagic]
private predicate paramFlowsThroughInPartialPath(
ParameterNode p, ReturnKind kind, CallContextCall cc, AccessPathNil apnil, Configuration config
ParameterNode p, ReturnKind kind, CallContextCall cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(PartialPathNodePriv mid, ReturnNode ret |
mid.getNode() = ret and
@@ -2362,9 +2418,9 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
AccessPathNil apnil, Configuration config
PartialAccessPathNil apnil, Configuration config
) {
exists(ParameterNode p, CallContext innercc, AccessPathNil midapnil |
exists(ParameterNode p, CallContext innercc, PartialAccessPathNil midapnil |
partialPathIntoCallable(mid, p, cc, innercc, call, midapnil, config) and
paramFlowsThroughInPartialPath(p, kind, innercc, apnil, config) and
not parameterValueFlowsThrough(p, kind, innercc)
@@ -2372,7 +2428,8 @@ private module FlowExploration {
}
private predicate partialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPathNil apnil, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
partialPathThroughCallable0(call, mid, kind, cc, apnil, config) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
pragma[noinline]
private predicate valuePartialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc |
partialPathIntoCallable(mid, p, cc, innercc, call, ap, config) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
}
private predicate valuePartialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
valuePartialPathThroughCallable0(call, mid, kind, cc, ap, config) and

View File

@@ -2048,11 +2048,64 @@ private module FlowExploration {
result = distSrcExt(TCallable(c, config)) - 1
}
private newtype TPartialAccessPath =
TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
* Conceptually a list of `Content`s followed by a `Type`, but only the first
* element of the list and its length are tracked. If data flows from a source to
* a given node with a given `AccessPath`, this indicates the sequence of
* dereference operations needed to get from the value in the node to the
* tracked object. The final type indicates the type of the tracked object.
*/
private class PartialAccessPath extends TPartialAccessPath {
abstract string toString();
Content getHead() { this = TPartialCons(result, _) }
int len() {
this = TPartialNil(_) and result = 0
or
this = TPartialCons(_, result)
}
DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
}
abstract AccessPathFront getFront();
}
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
exists(DataFlowType t | this = TPartialNil(t) | result = ppReprType(t))
}
override AccessPathFront getFront() {
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
private class PartialAccessPathCons extends PartialAccessPath, TPartialCons {
override string toString() {
exists(Content f, int len | this = TPartialCons(f, len) |
result = f.toString() + ", ... (" + len.toString() + ")"
)
}
override AccessPathFront getFront() {
exists(Content f | this = TPartialCons(f, _) | result = TFrontHead(f))
}
}
private newtype TPartialPathNode =
TPartialPathNodeMk(Node node, CallContext cc, AccessPath ap, Configuration config) {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedRepr(node.getType())) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathNodeMk0(
Node node, CallContext cc, AccessPath ap, Configuration config
Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
CallContext cc;
AccessPath ap;
PartialAccessPath ap;
Configuration config;
@@ -2148,7 +2201,7 @@ private module FlowExploration {
CallContext getCallContext() { result = cc }
AccessPath getAp() { result = ap }
PartialAccessPath getAp() { result = ap }
override Configuration getConfiguration() { result = config }
@@ -2161,7 +2214,7 @@ private module FlowExploration {
}
private predicate partialPathStep(
PartialPathNodePriv mid, Node node, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
or
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
jumpStep(mid.getNode(), node, config) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
or
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
cc = mid.getCallContext() and
config = mid.getConfiguration()
or
exists(AccessPath ap0, Content f |
exists(PartialAccessPath ap0, Content f |
partialPathReadStep(mid, ap0, f, node, cc, config) and
apConsFwd(ap, f, ap0, config)
)
@@ -2210,7 +2263,7 @@ private module FlowExploration {
pragma[inline]
private predicate partialPathStoreStep(
PartialPathNodePriv mid, AccessPath ap1, Content f, Node node, AccessPath ap2
PartialPathNodePriv mid, PartialAccessPath ap1, Content f, Node node, PartialAccessPath ap2
) {
ap1 = mid.getAp() and
store(mid.getNode(), f, node) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
}
pragma[nomagic]
private predicate apConsFwd(AccessPath ap1, Content f, AccessPath ap2, Configuration config) {
private predicate apConsFwd(
PartialAccessPath ap1, Content f, PartialAccessPath ap2, Configuration config
) {
exists(PartialPathNodePriv mid |
partialPathStoreStep(mid, ap1, f, _, ap2) and
config = mid.getConfiguration()
@@ -2229,7 +2284,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathReadStep(
PartialPathNodePriv mid, AccessPath ap, Content f, Node node, CallContext cc,
PartialPathNodePriv mid, PartialAccessPath ap, Content f, Node node, CallContext cc,
Configuration config
) {
ap = mid.getAp() and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable0(
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, AccessPath ap,
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap,
Configuration config
) {
pos = getReturnPosition(mid.getNode()) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathOutOfCallable1(
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc |
partialPathOutOfCallable0(mid, pos, innercc, ap, config) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(ReturnKind kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, cc, ap, config)
@@ -2276,7 +2331,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfArgument(
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, AccessPath ap,
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, PartialAccessPath ap,
Configuration config
) {
exists(
@@ -2302,7 +2357,7 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodePriv mid, int i, CallContext cc, DataFlowCall call, boolean emptyAp,
AccessPath ap, Configuration config
PartialAccessPath ap, Configuration config
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
@@ -2311,16 +2366,16 @@ private module FlowExploration {
ap = mid.getAp() and
config = mid.getConfiguration()
|
ap instanceof AccessPathNil and emptyAp = true
ap instanceof PartialAccessPathNil and emptyAp = true
or
ap instanceof AccessPathCons and emptyAp = false
ap instanceof PartialAccessPathCons and emptyAp = false
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodePriv mid, DataFlowCallable callable, int i, CallContext outercc,
DataFlowCall call, boolean emptyAp, AccessPath ap, Configuration config
DataFlowCall call, boolean emptyAp, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, emptyAp, ap, config) and
callable = resolveCall(call, outercc)
@@ -2328,7 +2383,7 @@ private module FlowExploration {
private predicate partialPathIntoCallable(
PartialPathNodePriv mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
DataFlowCall call, AccessPath ap, Configuration config
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
exists(int i, DataFlowCallable callable, boolean emptyAp |
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
pragma[nomagic]
private predicate paramFlowsThroughInPartialPath(
ParameterNode p, ReturnKind kind, CallContextCall cc, AccessPathNil apnil, Configuration config
ParameterNode p, ReturnKind kind, CallContextCall cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(PartialPathNodePriv mid, ReturnNode ret |
mid.getNode() = ret and
@@ -2362,9 +2418,9 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
AccessPathNil apnil, Configuration config
PartialAccessPathNil apnil, Configuration config
) {
exists(ParameterNode p, CallContext innercc, AccessPathNil midapnil |
exists(ParameterNode p, CallContext innercc, PartialAccessPathNil midapnil |
partialPathIntoCallable(mid, p, cc, innercc, call, midapnil, config) and
paramFlowsThroughInPartialPath(p, kind, innercc, apnil, config) and
not parameterValueFlowsThrough(p, kind, innercc)
@@ -2372,7 +2428,8 @@ private module FlowExploration {
}
private predicate partialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPathNil apnil, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
partialPathThroughCallable0(call, mid, kind, cc, apnil, config) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
pragma[noinline]
private predicate valuePartialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc |
partialPathIntoCallable(mid, p, cc, innercc, call, ap, config) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
}
private predicate valuePartialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
valuePartialPathThroughCallable0(call, mid, kind, cc, ap, config) and

View File

@@ -2048,11 +2048,64 @@ private module FlowExploration {
result = distSrcExt(TCallable(c, config)) - 1
}
private newtype TPartialAccessPath =
TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
* Conceptually a list of `Content`s followed by a `Type`, but only the first
* element of the list and its length are tracked. If data flows from a source to
* a given node with a given `AccessPath`, this indicates the sequence of
* dereference operations needed to get from the value in the node to the
* tracked object. The final type indicates the type of the tracked object.
*/
private class PartialAccessPath extends TPartialAccessPath {
abstract string toString();
Content getHead() { this = TPartialCons(result, _) }
int len() {
this = TPartialNil(_) and result = 0
or
this = TPartialCons(_, result)
}
DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
}
abstract AccessPathFront getFront();
}
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
exists(DataFlowType t | this = TPartialNil(t) | result = ppReprType(t))
}
override AccessPathFront getFront() {
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
private class PartialAccessPathCons extends PartialAccessPath, TPartialCons {
override string toString() {
exists(Content f, int len | this = TPartialCons(f, len) |
result = f.toString() + ", ... (" + len.toString() + ")"
)
}
override AccessPathFront getFront() {
exists(Content f | this = TPartialCons(f, _) | result = TFrontHead(f))
}
}
private newtype TPartialPathNode =
TPartialPathNodeMk(Node node, CallContext cc, AccessPath ap, Configuration config) {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedRepr(node.getType())) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathNodeMk0(
Node node, CallContext cc, AccessPath ap, Configuration config
Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
CallContext cc;
AccessPath ap;
PartialAccessPath ap;
Configuration config;
@@ -2148,7 +2201,7 @@ private module FlowExploration {
CallContext getCallContext() { result = cc }
AccessPath getAp() { result = ap }
PartialAccessPath getAp() { result = ap }
override Configuration getConfiguration() { result = config }
@@ -2161,7 +2214,7 @@ private module FlowExploration {
}
private predicate partialPathStep(
PartialPathNodePriv mid, Node node, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
or
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
jumpStep(mid.getNode(), node, config) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
or
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
cc = mid.getCallContext() and
config = mid.getConfiguration()
or
exists(AccessPath ap0, Content f |
exists(PartialAccessPath ap0, Content f |
partialPathReadStep(mid, ap0, f, node, cc, config) and
apConsFwd(ap, f, ap0, config)
)
@@ -2210,7 +2263,7 @@ private module FlowExploration {
pragma[inline]
private predicate partialPathStoreStep(
PartialPathNodePriv mid, AccessPath ap1, Content f, Node node, AccessPath ap2
PartialPathNodePriv mid, PartialAccessPath ap1, Content f, Node node, PartialAccessPath ap2
) {
ap1 = mid.getAp() and
store(mid.getNode(), f, node) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
}
pragma[nomagic]
private predicate apConsFwd(AccessPath ap1, Content f, AccessPath ap2, Configuration config) {
private predicate apConsFwd(
PartialAccessPath ap1, Content f, PartialAccessPath ap2, Configuration config
) {
exists(PartialPathNodePriv mid |
partialPathStoreStep(mid, ap1, f, _, ap2) and
config = mid.getConfiguration()
@@ -2229,7 +2284,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathReadStep(
PartialPathNodePriv mid, AccessPath ap, Content f, Node node, CallContext cc,
PartialPathNodePriv mid, PartialAccessPath ap, Content f, Node node, CallContext cc,
Configuration config
) {
ap = mid.getAp() and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable0(
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, AccessPath ap,
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap,
Configuration config
) {
pos = getReturnPosition(mid.getNode()) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathOutOfCallable1(
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc |
partialPathOutOfCallable0(mid, pos, innercc, ap, config) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(ReturnKind kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, cc, ap, config)
@@ -2276,7 +2331,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfArgument(
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, AccessPath ap,
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, PartialAccessPath ap,
Configuration config
) {
exists(
@@ -2302,7 +2357,7 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodePriv mid, int i, CallContext cc, DataFlowCall call, boolean emptyAp,
AccessPath ap, Configuration config
PartialAccessPath ap, Configuration config
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
@@ -2311,16 +2366,16 @@ private module FlowExploration {
ap = mid.getAp() and
config = mid.getConfiguration()
|
ap instanceof AccessPathNil and emptyAp = true
ap instanceof PartialAccessPathNil and emptyAp = true
or
ap instanceof AccessPathCons and emptyAp = false
ap instanceof PartialAccessPathCons and emptyAp = false
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodePriv mid, DataFlowCallable callable, int i, CallContext outercc,
DataFlowCall call, boolean emptyAp, AccessPath ap, Configuration config
DataFlowCall call, boolean emptyAp, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, emptyAp, ap, config) and
callable = resolveCall(call, outercc)
@@ -2328,7 +2383,7 @@ private module FlowExploration {
private predicate partialPathIntoCallable(
PartialPathNodePriv mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
DataFlowCall call, AccessPath ap, Configuration config
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
exists(int i, DataFlowCallable callable, boolean emptyAp |
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
pragma[nomagic]
private predicate paramFlowsThroughInPartialPath(
ParameterNode p, ReturnKind kind, CallContextCall cc, AccessPathNil apnil, Configuration config
ParameterNode p, ReturnKind kind, CallContextCall cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(PartialPathNodePriv mid, ReturnNode ret |
mid.getNode() = ret and
@@ -2362,9 +2418,9 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
AccessPathNil apnil, Configuration config
PartialAccessPathNil apnil, Configuration config
) {
exists(ParameterNode p, CallContext innercc, AccessPathNil midapnil |
exists(ParameterNode p, CallContext innercc, PartialAccessPathNil midapnil |
partialPathIntoCallable(mid, p, cc, innercc, call, midapnil, config) and
paramFlowsThroughInPartialPath(p, kind, innercc, apnil, config) and
not parameterValueFlowsThrough(p, kind, innercc)
@@ -2372,7 +2428,8 @@ private module FlowExploration {
}
private predicate partialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPathNil apnil, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
partialPathThroughCallable0(call, mid, kind, cc, apnil, config) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
pragma[noinline]
private predicate valuePartialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc |
partialPathIntoCallable(mid, p, cc, innercc, call, ap, config) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
}
private predicate valuePartialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
valuePartialPathThroughCallable0(call, mid, kind, cc, ap, config) and

View File

@@ -2048,11 +2048,64 @@ private module FlowExploration {
result = distSrcExt(TCallable(c, config)) - 1
}
private newtype TPartialAccessPath =
TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
* Conceptually a list of `Content`s followed by a `Type`, but only the first
* element of the list and its length are tracked. If data flows from a source to
* a given node with a given `AccessPath`, this indicates the sequence of
* dereference operations needed to get from the value in the node to the
* tracked object. The final type indicates the type of the tracked object.
*/
private class PartialAccessPath extends TPartialAccessPath {
abstract string toString();
Content getHead() { this = TPartialCons(result, _) }
int len() {
this = TPartialNil(_) and result = 0
or
this = TPartialCons(_, result)
}
DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
}
abstract AccessPathFront getFront();
}
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
exists(DataFlowType t | this = TPartialNil(t) | result = ppReprType(t))
}
override AccessPathFront getFront() {
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
private class PartialAccessPathCons extends PartialAccessPath, TPartialCons {
override string toString() {
exists(Content f, int len | this = TPartialCons(f, len) |
result = f.toString() + ", ... (" + len.toString() + ")"
)
}
override AccessPathFront getFront() {
exists(Content f | this = TPartialCons(f, _) | result = TFrontHead(f))
}
}
private newtype TPartialPathNode =
TPartialPathNodeMk(Node node, CallContext cc, AccessPath ap, Configuration config) {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedRepr(node.getType())) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathNodeMk0(
Node node, CallContext cc, AccessPath ap, Configuration config
Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
CallContext cc;
AccessPath ap;
PartialAccessPath ap;
Configuration config;
@@ -2148,7 +2201,7 @@ private module FlowExploration {
CallContext getCallContext() { result = cc }
AccessPath getAp() { result = ap }
PartialAccessPath getAp() { result = ap }
override Configuration getConfiguration() { result = config }
@@ -2161,7 +2214,7 @@ private module FlowExploration {
}
private predicate partialPathStep(
PartialPathNodePriv mid, Node node, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
or
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
jumpStep(mid.getNode(), node, config) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
or
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
cc = mid.getCallContext() and
config = mid.getConfiguration()
or
exists(AccessPath ap0, Content f |
exists(PartialAccessPath ap0, Content f |
partialPathReadStep(mid, ap0, f, node, cc, config) and
apConsFwd(ap, f, ap0, config)
)
@@ -2210,7 +2263,7 @@ private module FlowExploration {
pragma[inline]
private predicate partialPathStoreStep(
PartialPathNodePriv mid, AccessPath ap1, Content f, Node node, AccessPath ap2
PartialPathNodePriv mid, PartialAccessPath ap1, Content f, Node node, PartialAccessPath ap2
) {
ap1 = mid.getAp() and
store(mid.getNode(), f, node) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
}
pragma[nomagic]
private predicate apConsFwd(AccessPath ap1, Content f, AccessPath ap2, Configuration config) {
private predicate apConsFwd(
PartialAccessPath ap1, Content f, PartialAccessPath ap2, Configuration config
) {
exists(PartialPathNodePriv mid |
partialPathStoreStep(mid, ap1, f, _, ap2) and
config = mid.getConfiguration()
@@ -2229,7 +2284,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathReadStep(
PartialPathNodePriv mid, AccessPath ap, Content f, Node node, CallContext cc,
PartialPathNodePriv mid, PartialAccessPath ap, Content f, Node node, CallContext cc,
Configuration config
) {
ap = mid.getAp() and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable0(
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, AccessPath ap,
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap,
Configuration config
) {
pos = getReturnPosition(mid.getNode()) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathOutOfCallable1(
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc |
partialPathOutOfCallable0(mid, pos, innercc, ap, config) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(ReturnKind kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, cc, ap, config)
@@ -2276,7 +2331,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfArgument(
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, AccessPath ap,
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, PartialAccessPath ap,
Configuration config
) {
exists(
@@ -2302,7 +2357,7 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodePriv mid, int i, CallContext cc, DataFlowCall call, boolean emptyAp,
AccessPath ap, Configuration config
PartialAccessPath ap, Configuration config
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
@@ -2311,16 +2366,16 @@ private module FlowExploration {
ap = mid.getAp() and
config = mid.getConfiguration()
|
ap instanceof AccessPathNil and emptyAp = true
ap instanceof PartialAccessPathNil and emptyAp = true
or
ap instanceof AccessPathCons and emptyAp = false
ap instanceof PartialAccessPathCons and emptyAp = false
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodePriv mid, DataFlowCallable callable, int i, CallContext outercc,
DataFlowCall call, boolean emptyAp, AccessPath ap, Configuration config
DataFlowCall call, boolean emptyAp, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, emptyAp, ap, config) and
callable = resolveCall(call, outercc)
@@ -2328,7 +2383,7 @@ private module FlowExploration {
private predicate partialPathIntoCallable(
PartialPathNodePriv mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
DataFlowCall call, AccessPath ap, Configuration config
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
exists(int i, DataFlowCallable callable, boolean emptyAp |
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
pragma[nomagic]
private predicate paramFlowsThroughInPartialPath(
ParameterNode p, ReturnKind kind, CallContextCall cc, AccessPathNil apnil, Configuration config
ParameterNode p, ReturnKind kind, CallContextCall cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(PartialPathNodePriv mid, ReturnNode ret |
mid.getNode() = ret and
@@ -2362,9 +2418,9 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
AccessPathNil apnil, Configuration config
PartialAccessPathNil apnil, Configuration config
) {
exists(ParameterNode p, CallContext innercc, AccessPathNil midapnil |
exists(ParameterNode p, CallContext innercc, PartialAccessPathNil midapnil |
partialPathIntoCallable(mid, p, cc, innercc, call, midapnil, config) and
paramFlowsThroughInPartialPath(p, kind, innercc, apnil, config) and
not parameterValueFlowsThrough(p, kind, innercc)
@@ -2372,7 +2428,8 @@ private module FlowExploration {
}
private predicate partialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPathNil apnil, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
partialPathThroughCallable0(call, mid, kind, cc, apnil, config) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
pragma[noinline]
private predicate valuePartialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc |
partialPathIntoCallable(mid, p, cc, innercc, call, ap, config) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
}
private predicate valuePartialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
valuePartialPathThroughCallable0(call, mid, kind, cc, ap, config) and

View File

@@ -2048,11 +2048,64 @@ private module FlowExploration {
result = distSrcExt(TCallable(c, config)) - 1
}
private newtype TPartialAccessPath =
TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
* Conceptually a list of `Content`s followed by a `Type`, but only the first
* element of the list and its length are tracked. If data flows from a source to
* a given node with a given `AccessPath`, this indicates the sequence of
* dereference operations needed to get from the value in the node to the
* tracked object. The final type indicates the type of the tracked object.
*/
private class PartialAccessPath extends TPartialAccessPath {
abstract string toString();
Content getHead() { this = TPartialCons(result, _) }
int len() {
this = TPartialNil(_) and result = 0
or
this = TPartialCons(_, result)
}
DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
}
abstract AccessPathFront getFront();
}
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
exists(DataFlowType t | this = TPartialNil(t) | result = ppReprType(t))
}
override AccessPathFront getFront() {
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
private class PartialAccessPathCons extends PartialAccessPath, TPartialCons {
override string toString() {
exists(Content f, int len | this = TPartialCons(f, len) |
result = f.toString() + ", ... (" + len.toString() + ")"
)
}
override AccessPathFront getFront() {
exists(Content f | this = TPartialCons(f, _) | result = TFrontHead(f))
}
}
private newtype TPartialPathNode =
TPartialPathNodeMk(Node node, CallContext cc, AccessPath ap, Configuration config) {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedRepr(node.getType())) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathNodeMk0(
Node node, CallContext cc, AccessPath ap, Configuration config
Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
CallContext cc;
AccessPath ap;
PartialAccessPath ap;
Configuration config;
@@ -2148,7 +2201,7 @@ private module FlowExploration {
CallContext getCallContext() { result = cc }
AccessPath getAp() { result = ap }
PartialAccessPath getAp() { result = ap }
override Configuration getConfiguration() { result = config }
@@ -2161,7 +2214,7 @@ private module FlowExploration {
}
private predicate partialPathStep(
PartialPathNodePriv mid, Node node, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
or
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
jumpStep(mid.getNode(), node, config) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
or
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
cc = mid.getCallContext() and
config = mid.getConfiguration()
or
exists(AccessPath ap0, Content f |
exists(PartialAccessPath ap0, Content f |
partialPathReadStep(mid, ap0, f, node, cc, config) and
apConsFwd(ap, f, ap0, config)
)
@@ -2210,7 +2263,7 @@ private module FlowExploration {
pragma[inline]
private predicate partialPathStoreStep(
PartialPathNodePriv mid, AccessPath ap1, Content f, Node node, AccessPath ap2
PartialPathNodePriv mid, PartialAccessPath ap1, Content f, Node node, PartialAccessPath ap2
) {
ap1 = mid.getAp() and
store(mid.getNode(), f, node) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
}
pragma[nomagic]
private predicate apConsFwd(AccessPath ap1, Content f, AccessPath ap2, Configuration config) {
private predicate apConsFwd(
PartialAccessPath ap1, Content f, PartialAccessPath ap2, Configuration config
) {
exists(PartialPathNodePriv mid |
partialPathStoreStep(mid, ap1, f, _, ap2) and
config = mid.getConfiguration()
@@ -2229,7 +2284,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathReadStep(
PartialPathNodePriv mid, AccessPath ap, Content f, Node node, CallContext cc,
PartialPathNodePriv mid, PartialAccessPath ap, Content f, Node node, CallContext cc,
Configuration config
) {
ap = mid.getAp() and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable0(
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, AccessPath ap,
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap,
Configuration config
) {
pos = getReturnPosition(mid.getNode()) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathOutOfCallable1(
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc |
partialPathOutOfCallable0(mid, pos, innercc, ap, config) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(ReturnKind kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, cc, ap, config)
@@ -2276,7 +2331,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfArgument(
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, AccessPath ap,
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, PartialAccessPath ap,
Configuration config
) {
exists(
@@ -2302,7 +2357,7 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodePriv mid, int i, CallContext cc, DataFlowCall call, boolean emptyAp,
AccessPath ap, Configuration config
PartialAccessPath ap, Configuration config
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
@@ -2311,16 +2366,16 @@ private module FlowExploration {
ap = mid.getAp() and
config = mid.getConfiguration()
|
ap instanceof AccessPathNil and emptyAp = true
ap instanceof PartialAccessPathNil and emptyAp = true
or
ap instanceof AccessPathCons and emptyAp = false
ap instanceof PartialAccessPathCons and emptyAp = false
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodePriv mid, DataFlowCallable callable, int i, CallContext outercc,
DataFlowCall call, boolean emptyAp, AccessPath ap, Configuration config
DataFlowCall call, boolean emptyAp, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, emptyAp, ap, config) and
callable = resolveCall(call, outercc)
@@ -2328,7 +2383,7 @@ private module FlowExploration {
private predicate partialPathIntoCallable(
PartialPathNodePriv mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
DataFlowCall call, AccessPath ap, Configuration config
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
exists(int i, DataFlowCallable callable, boolean emptyAp |
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
pragma[nomagic]
private predicate paramFlowsThroughInPartialPath(
ParameterNode p, ReturnKind kind, CallContextCall cc, AccessPathNil apnil, Configuration config
ParameterNode p, ReturnKind kind, CallContextCall cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(PartialPathNodePriv mid, ReturnNode ret |
mid.getNode() = ret and
@@ -2362,9 +2418,9 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
AccessPathNil apnil, Configuration config
PartialAccessPathNil apnil, Configuration config
) {
exists(ParameterNode p, CallContext innercc, AccessPathNil midapnil |
exists(ParameterNode p, CallContext innercc, PartialAccessPathNil midapnil |
partialPathIntoCallable(mid, p, cc, innercc, call, midapnil, config) and
paramFlowsThroughInPartialPath(p, kind, innercc, apnil, config) and
not parameterValueFlowsThrough(p, kind, innercc)
@@ -2372,7 +2428,8 @@ private module FlowExploration {
}
private predicate partialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPathNil apnil, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
partialPathThroughCallable0(call, mid, kind, cc, apnil, config) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
pragma[noinline]
private predicate valuePartialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc |
partialPathIntoCallable(mid, p, cc, innercc, call, ap, config) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
}
private predicate valuePartialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
valuePartialPathThroughCallable0(call, mid, kind, cc, ap, config) and

View File

@@ -2048,11 +2048,64 @@ private module FlowExploration {
result = distSrcExt(TCallable(c, config)) - 1
}
private newtype TPartialAccessPath =
TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
* Conceptually a list of `Content`s followed by a `Type`, but only the first
* element of the list and its length are tracked. If data flows from a source to
* a given node with a given `AccessPath`, this indicates the sequence of
* dereference operations needed to get from the value in the node to the
* tracked object. The final type indicates the type of the tracked object.
*/
private class PartialAccessPath extends TPartialAccessPath {
abstract string toString();
Content getHead() { this = TPartialCons(result, _) }
int len() {
this = TPartialNil(_) and result = 0
or
this = TPartialCons(_, result)
}
DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
}
abstract AccessPathFront getFront();
}
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
exists(DataFlowType t | this = TPartialNil(t) | result = ppReprType(t))
}
override AccessPathFront getFront() {
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
private class PartialAccessPathCons extends PartialAccessPath, TPartialCons {
override string toString() {
exists(Content f, int len | this = TPartialCons(f, len) |
result = f.toString() + ", ... (" + len.toString() + ")"
)
}
override AccessPathFront getFront() {
exists(Content f | this = TPartialCons(f, _) | result = TFrontHead(f))
}
}
private newtype TPartialPathNode =
TPartialPathNodeMk(Node node, CallContext cc, AccessPath ap, Configuration config) {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedRepr(node.getType())) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathNodeMk0(
Node node, CallContext cc, AccessPath ap, Configuration config
Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
CallContext cc;
AccessPath ap;
PartialAccessPath ap;
Configuration config;
@@ -2148,7 +2201,7 @@ private module FlowExploration {
CallContext getCallContext() { result = cc }
AccessPath getAp() { result = ap }
PartialAccessPath getAp() { result = ap }
override Configuration getConfiguration() { result = config }
@@ -2161,7 +2214,7 @@ private module FlowExploration {
}
private predicate partialPathStep(
PartialPathNodePriv mid, Node node, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
or
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
jumpStep(mid.getNode(), node, config) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
or
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
cc = mid.getCallContext() and
config = mid.getConfiguration()
or
exists(AccessPath ap0, Content f |
exists(PartialAccessPath ap0, Content f |
partialPathReadStep(mid, ap0, f, node, cc, config) and
apConsFwd(ap, f, ap0, config)
)
@@ -2210,7 +2263,7 @@ private module FlowExploration {
pragma[inline]
private predicate partialPathStoreStep(
PartialPathNodePriv mid, AccessPath ap1, Content f, Node node, AccessPath ap2
PartialPathNodePriv mid, PartialAccessPath ap1, Content f, Node node, PartialAccessPath ap2
) {
ap1 = mid.getAp() and
store(mid.getNode(), f, node) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
}
pragma[nomagic]
private predicate apConsFwd(AccessPath ap1, Content f, AccessPath ap2, Configuration config) {
private predicate apConsFwd(
PartialAccessPath ap1, Content f, PartialAccessPath ap2, Configuration config
) {
exists(PartialPathNodePriv mid |
partialPathStoreStep(mid, ap1, f, _, ap2) and
config = mid.getConfiguration()
@@ -2229,7 +2284,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathReadStep(
PartialPathNodePriv mid, AccessPath ap, Content f, Node node, CallContext cc,
PartialPathNodePriv mid, PartialAccessPath ap, Content f, Node node, CallContext cc,
Configuration config
) {
ap = mid.getAp() and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable0(
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, AccessPath ap,
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap,
Configuration config
) {
pos = getReturnPosition(mid.getNode()) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathOutOfCallable1(
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc |
partialPathOutOfCallable0(mid, pos, innercc, ap, config) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(ReturnKind kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, cc, ap, config)
@@ -2276,7 +2331,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfArgument(
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, AccessPath ap,
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, PartialAccessPath ap,
Configuration config
) {
exists(
@@ -2302,7 +2357,7 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodePriv mid, int i, CallContext cc, DataFlowCall call, boolean emptyAp,
AccessPath ap, Configuration config
PartialAccessPath ap, Configuration config
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
@@ -2311,16 +2366,16 @@ private module FlowExploration {
ap = mid.getAp() and
config = mid.getConfiguration()
|
ap instanceof AccessPathNil and emptyAp = true
ap instanceof PartialAccessPathNil and emptyAp = true
or
ap instanceof AccessPathCons and emptyAp = false
ap instanceof PartialAccessPathCons and emptyAp = false
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodePriv mid, DataFlowCallable callable, int i, CallContext outercc,
DataFlowCall call, boolean emptyAp, AccessPath ap, Configuration config
DataFlowCall call, boolean emptyAp, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, emptyAp, ap, config) and
callable = resolveCall(call, outercc)
@@ -2328,7 +2383,7 @@ private module FlowExploration {
private predicate partialPathIntoCallable(
PartialPathNodePriv mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
DataFlowCall call, AccessPath ap, Configuration config
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
exists(int i, DataFlowCallable callable, boolean emptyAp |
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
pragma[nomagic]
private predicate paramFlowsThroughInPartialPath(
ParameterNode p, ReturnKind kind, CallContextCall cc, AccessPathNil apnil, Configuration config
ParameterNode p, ReturnKind kind, CallContextCall cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(PartialPathNodePriv mid, ReturnNode ret |
mid.getNode() = ret and
@@ -2362,9 +2418,9 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
AccessPathNil apnil, Configuration config
PartialAccessPathNil apnil, Configuration config
) {
exists(ParameterNode p, CallContext innercc, AccessPathNil midapnil |
exists(ParameterNode p, CallContext innercc, PartialAccessPathNil midapnil |
partialPathIntoCallable(mid, p, cc, innercc, call, midapnil, config) and
paramFlowsThroughInPartialPath(p, kind, innercc, apnil, config) and
not parameterValueFlowsThrough(p, kind, innercc)
@@ -2372,7 +2428,8 @@ private module FlowExploration {
}
private predicate partialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPathNil apnil, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
partialPathThroughCallable0(call, mid, kind, cc, apnil, config) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
pragma[noinline]
private predicate valuePartialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc |
partialPathIntoCallable(mid, p, cc, innercc, call, ap, config) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
}
private predicate valuePartialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
valuePartialPathThroughCallable0(call, mid, kind, cc, ap, config) and

View File

@@ -2048,11 +2048,64 @@ private module FlowExploration {
result = distSrcExt(TCallable(c, config)) - 1
}
private newtype TPartialAccessPath =
TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
* Conceptually a list of `Content`s followed by a `Type`, but only the first
* element of the list and its length are tracked. If data flows from a source to
* a given node with a given `AccessPath`, this indicates the sequence of
* dereference operations needed to get from the value in the node to the
* tracked object. The final type indicates the type of the tracked object.
*/
private class PartialAccessPath extends TPartialAccessPath {
abstract string toString();
Content getHead() { this = TPartialCons(result, _) }
int len() {
this = TPartialNil(_) and result = 0
or
this = TPartialCons(_, result)
}
DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
}
abstract AccessPathFront getFront();
}
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
exists(DataFlowType t | this = TPartialNil(t) | result = ppReprType(t))
}
override AccessPathFront getFront() {
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
private class PartialAccessPathCons extends PartialAccessPath, TPartialCons {
override string toString() {
exists(Content f, int len | this = TPartialCons(f, len) |
result = f.toString() + ", ... (" + len.toString() + ")"
)
}
override AccessPathFront getFront() {
exists(Content f | this = TPartialCons(f, _) | result = TFrontHead(f))
}
}
private newtype TPartialPathNode =
TPartialPathNodeMk(Node node, CallContext cc, AccessPath ap, Configuration config) {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedRepr(node.getType())) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathNodeMk0(
Node node, CallContext cc, AccessPath ap, Configuration config
Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
CallContext cc;
AccessPath ap;
PartialAccessPath ap;
Configuration config;
@@ -2148,7 +2201,7 @@ private module FlowExploration {
CallContext getCallContext() { result = cc }
AccessPath getAp() { result = ap }
PartialAccessPath getAp() { result = ap }
override Configuration getConfiguration() { result = config }
@@ -2161,7 +2214,7 @@ private module FlowExploration {
}
private predicate partialPathStep(
PartialPathNodePriv mid, Node node, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
or
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
jumpStep(mid.getNode(), node, config) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
or
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
cc = mid.getCallContext() and
config = mid.getConfiguration()
or
exists(AccessPath ap0, Content f |
exists(PartialAccessPath ap0, Content f |
partialPathReadStep(mid, ap0, f, node, cc, config) and
apConsFwd(ap, f, ap0, config)
)
@@ -2210,7 +2263,7 @@ private module FlowExploration {
pragma[inline]
private predicate partialPathStoreStep(
PartialPathNodePriv mid, AccessPath ap1, Content f, Node node, AccessPath ap2
PartialPathNodePriv mid, PartialAccessPath ap1, Content f, Node node, PartialAccessPath ap2
) {
ap1 = mid.getAp() and
store(mid.getNode(), f, node) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
}
pragma[nomagic]
private predicate apConsFwd(AccessPath ap1, Content f, AccessPath ap2, Configuration config) {
private predicate apConsFwd(
PartialAccessPath ap1, Content f, PartialAccessPath ap2, Configuration config
) {
exists(PartialPathNodePriv mid |
partialPathStoreStep(mid, ap1, f, _, ap2) and
config = mid.getConfiguration()
@@ -2229,7 +2284,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathReadStep(
PartialPathNodePriv mid, AccessPath ap, Content f, Node node, CallContext cc,
PartialPathNodePriv mid, PartialAccessPath ap, Content f, Node node, CallContext cc,
Configuration config
) {
ap = mid.getAp() and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable0(
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, AccessPath ap,
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap,
Configuration config
) {
pos = getReturnPosition(mid.getNode()) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathOutOfCallable1(
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc |
partialPathOutOfCallable0(mid, pos, innercc, ap, config) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(ReturnKind kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, cc, ap, config)
@@ -2276,7 +2331,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfArgument(
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, AccessPath ap,
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, PartialAccessPath ap,
Configuration config
) {
exists(
@@ -2302,7 +2357,7 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodePriv mid, int i, CallContext cc, DataFlowCall call, boolean emptyAp,
AccessPath ap, Configuration config
PartialAccessPath ap, Configuration config
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
@@ -2311,16 +2366,16 @@ private module FlowExploration {
ap = mid.getAp() and
config = mid.getConfiguration()
|
ap instanceof AccessPathNil and emptyAp = true
ap instanceof PartialAccessPathNil and emptyAp = true
or
ap instanceof AccessPathCons and emptyAp = false
ap instanceof PartialAccessPathCons and emptyAp = false
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodePriv mid, DataFlowCallable callable, int i, CallContext outercc,
DataFlowCall call, boolean emptyAp, AccessPath ap, Configuration config
DataFlowCall call, boolean emptyAp, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, emptyAp, ap, config) and
callable = resolveCall(call, outercc)
@@ -2328,7 +2383,7 @@ private module FlowExploration {
private predicate partialPathIntoCallable(
PartialPathNodePriv mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
DataFlowCall call, AccessPath ap, Configuration config
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
exists(int i, DataFlowCallable callable, boolean emptyAp |
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
pragma[nomagic]
private predicate paramFlowsThroughInPartialPath(
ParameterNode p, ReturnKind kind, CallContextCall cc, AccessPathNil apnil, Configuration config
ParameterNode p, ReturnKind kind, CallContextCall cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(PartialPathNodePriv mid, ReturnNode ret |
mid.getNode() = ret and
@@ -2362,9 +2418,9 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
AccessPathNil apnil, Configuration config
PartialAccessPathNil apnil, Configuration config
) {
exists(ParameterNode p, CallContext innercc, AccessPathNil midapnil |
exists(ParameterNode p, CallContext innercc, PartialAccessPathNil midapnil |
partialPathIntoCallable(mid, p, cc, innercc, call, midapnil, config) and
paramFlowsThroughInPartialPath(p, kind, innercc, apnil, config) and
not parameterValueFlowsThrough(p, kind, innercc)
@@ -2372,7 +2428,8 @@ private module FlowExploration {
}
private predicate partialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPathNil apnil, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
partialPathThroughCallable0(call, mid, kind, cc, apnil, config) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
pragma[noinline]
private predicate valuePartialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc |
partialPathIntoCallable(mid, p, cc, innercc, call, ap, config) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
}
private predicate valuePartialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
valuePartialPathThroughCallable0(call, mid, kind, cc, ap, config) and

View File

@@ -2048,11 +2048,64 @@ private module FlowExploration {
result = distSrcExt(TCallable(c, config)) - 1
}
private newtype TPartialAccessPath =
TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
* Conceptually a list of `Content`s followed by a `Type`, but only the first
* element of the list and its length are tracked. If data flows from a source to
* a given node with a given `AccessPath`, this indicates the sequence of
* dereference operations needed to get from the value in the node to the
* tracked object. The final type indicates the type of the tracked object.
*/
private class PartialAccessPath extends TPartialAccessPath {
abstract string toString();
Content getHead() { this = TPartialCons(result, _) }
int len() {
this = TPartialNil(_) and result = 0
or
this = TPartialCons(_, result)
}
DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
}
abstract AccessPathFront getFront();
}
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
exists(DataFlowType t | this = TPartialNil(t) | result = ppReprType(t))
}
override AccessPathFront getFront() {
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
private class PartialAccessPathCons extends PartialAccessPath, TPartialCons {
override string toString() {
exists(Content f, int len | this = TPartialCons(f, len) |
result = f.toString() + ", ... (" + len.toString() + ")"
)
}
override AccessPathFront getFront() {
exists(Content f | this = TPartialCons(f, _) | result = TFrontHead(f))
}
}
private newtype TPartialPathNode =
TPartialPathNodeMk(Node node, CallContext cc, AccessPath ap, Configuration config) {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedRepr(node.getType())) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathNodeMk0(
Node node, CallContext cc, AccessPath ap, Configuration config
Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
CallContext cc;
AccessPath ap;
PartialAccessPath ap;
Configuration config;
@@ -2148,7 +2201,7 @@ private module FlowExploration {
CallContext getCallContext() { result = cc }
AccessPath getAp() { result = ap }
PartialAccessPath getAp() { result = ap }
override Configuration getConfiguration() { result = config }
@@ -2161,7 +2214,7 @@ private module FlowExploration {
}
private predicate partialPathStep(
PartialPathNodePriv mid, Node node, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
or
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
jumpStep(mid.getNode(), node, config) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
or
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
cc = mid.getCallContext() and
config = mid.getConfiguration()
or
exists(AccessPath ap0, Content f |
exists(PartialAccessPath ap0, Content f |
partialPathReadStep(mid, ap0, f, node, cc, config) and
apConsFwd(ap, f, ap0, config)
)
@@ -2210,7 +2263,7 @@ private module FlowExploration {
pragma[inline]
private predicate partialPathStoreStep(
PartialPathNodePriv mid, AccessPath ap1, Content f, Node node, AccessPath ap2
PartialPathNodePriv mid, PartialAccessPath ap1, Content f, Node node, PartialAccessPath ap2
) {
ap1 = mid.getAp() and
store(mid.getNode(), f, node) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
}
pragma[nomagic]
private predicate apConsFwd(AccessPath ap1, Content f, AccessPath ap2, Configuration config) {
private predicate apConsFwd(
PartialAccessPath ap1, Content f, PartialAccessPath ap2, Configuration config
) {
exists(PartialPathNodePriv mid |
partialPathStoreStep(mid, ap1, f, _, ap2) and
config = mid.getConfiguration()
@@ -2229,7 +2284,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathReadStep(
PartialPathNodePriv mid, AccessPath ap, Content f, Node node, CallContext cc,
PartialPathNodePriv mid, PartialAccessPath ap, Content f, Node node, CallContext cc,
Configuration config
) {
ap = mid.getAp() and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable0(
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, AccessPath ap,
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap,
Configuration config
) {
pos = getReturnPosition(mid.getNode()) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathOutOfCallable1(
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc |
partialPathOutOfCallable0(mid, pos, innercc, ap, config) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(ReturnKind kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, cc, ap, config)
@@ -2276,7 +2331,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfArgument(
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, AccessPath ap,
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, PartialAccessPath ap,
Configuration config
) {
exists(
@@ -2302,7 +2357,7 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodePriv mid, int i, CallContext cc, DataFlowCall call, boolean emptyAp,
AccessPath ap, Configuration config
PartialAccessPath ap, Configuration config
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
@@ -2311,16 +2366,16 @@ private module FlowExploration {
ap = mid.getAp() and
config = mid.getConfiguration()
|
ap instanceof AccessPathNil and emptyAp = true
ap instanceof PartialAccessPathNil and emptyAp = true
or
ap instanceof AccessPathCons and emptyAp = false
ap instanceof PartialAccessPathCons and emptyAp = false
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodePriv mid, DataFlowCallable callable, int i, CallContext outercc,
DataFlowCall call, boolean emptyAp, AccessPath ap, Configuration config
DataFlowCall call, boolean emptyAp, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, emptyAp, ap, config) and
callable = resolveCall(call, outercc)
@@ -2328,7 +2383,7 @@ private module FlowExploration {
private predicate partialPathIntoCallable(
PartialPathNodePriv mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
DataFlowCall call, AccessPath ap, Configuration config
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
exists(int i, DataFlowCallable callable, boolean emptyAp |
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
pragma[nomagic]
private predicate paramFlowsThroughInPartialPath(
ParameterNode p, ReturnKind kind, CallContextCall cc, AccessPathNil apnil, Configuration config
ParameterNode p, ReturnKind kind, CallContextCall cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(PartialPathNodePriv mid, ReturnNode ret |
mid.getNode() = ret and
@@ -2362,9 +2418,9 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
AccessPathNil apnil, Configuration config
PartialAccessPathNil apnil, Configuration config
) {
exists(ParameterNode p, CallContext innercc, AccessPathNil midapnil |
exists(ParameterNode p, CallContext innercc, PartialAccessPathNil midapnil |
partialPathIntoCallable(mid, p, cc, innercc, call, midapnil, config) and
paramFlowsThroughInPartialPath(p, kind, innercc, apnil, config) and
not parameterValueFlowsThrough(p, kind, innercc)
@@ -2372,7 +2428,8 @@ private module FlowExploration {
}
private predicate partialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPathNil apnil, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
partialPathThroughCallable0(call, mid, kind, cc, apnil, config) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
pragma[noinline]
private predicate valuePartialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc |
partialPathIntoCallable(mid, p, cc, innercc, call, ap, config) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
}
private predicate valuePartialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
valuePartialPathThroughCallable0(call, mid, kind, cc, ap, config) and

View File

@@ -2048,11 +2048,64 @@ private module FlowExploration {
result = distSrcExt(TCallable(c, config)) - 1
}
private newtype TPartialAccessPath =
TPartialNil(DataFlowType t) or
TPartialCons(Content f, int len) { len in [1 .. 5] }
/**
* Conceptually a list of `Content`s followed by a `Type`, but only the first
* element of the list and its length are tracked. If data flows from a source to
* a given node with a given `AccessPath`, this indicates the sequence of
* dereference operations needed to get from the value in the node to the
* tracked object. The final type indicates the type of the tracked object.
*/
private class PartialAccessPath extends TPartialAccessPath {
abstract string toString();
Content getHead() { this = TPartialCons(result, _) }
int len() {
this = TPartialNil(_) and result = 0
or
this = TPartialCons(_, result)
}
DataFlowType getType() {
this = TPartialNil(result)
or
exists(Content head | this = TPartialCons(head, _) | result = head.getContainerType())
}
abstract AccessPathFront getFront();
}
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
override string toString() {
exists(DataFlowType t | this = TPartialNil(t) | result = ppReprType(t))
}
override AccessPathFront getFront() {
exists(DataFlowType t | this = TPartialNil(t) | result = TFrontNil(t))
}
}
private class PartialAccessPathCons extends PartialAccessPath, TPartialCons {
override string toString() {
exists(Content f, int len | this = TPartialCons(f, len) |
result = f.toString() + ", ... (" + len.toString() + ")"
)
}
override AccessPathFront getFront() {
exists(Content f | this = TPartialCons(f, _) | result = TFrontHead(f))
}
}
private newtype TPartialPathNode =
TPartialPathNodeMk(Node node, CallContext cc, AccessPath ap, Configuration config) {
TPartialPathNodeMk(Node node, CallContext cc, PartialAccessPath ap, Configuration config) {
config.isSource(node) and
cc instanceof CallContextAny and
ap = TNil(getErasedRepr(node.getType())) and
ap = TPartialNil(getErasedRepr(node.getType())) and
not fullBarrier(node, config) and
exists(config.explorationLimit())
or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathNodeMk0(
Node node, CallContext cc, AccessPath ap, Configuration config
Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(PartialPathNode mid |
partialPathStep(mid, node, cc, ap, config) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
CallContext cc;
AccessPath ap;
PartialAccessPath ap;
Configuration config;
@@ -2148,7 +2201,7 @@ private module FlowExploration {
CallContext getCallContext() { result = cc }
AccessPath getAp() { result = ap }
PartialAccessPath getAp() { result = ap }
override Configuration getConfiguration() { result = config }
@@ -2161,7 +2214,7 @@ private module FlowExploration {
}
private predicate partialPathStep(
PartialPathNodePriv mid, Node node, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
) {
localFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
or
additionalLocalFlowStep(mid.getNode(), node, config) and
cc = mid.getCallContext() and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
jumpStep(mid.getNode(), node, config) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
or
additionalJumpStep(mid.getNode(), node, config) and
cc instanceof CallContextAny and
mid.getAp() instanceof AccessPathNil and
ap = TNil(getErasedRepr(node.getType())) and
mid.getAp() instanceof PartialAccessPathNil and
ap = TPartialNil(getErasedRepr(node.getType())) and
config = mid.getConfiguration()
or
partialPathStoreStep(mid, _, _, node, ap) and
cc = mid.getCallContext() and
config = mid.getConfiguration()
or
exists(AccessPath ap0, Content f |
exists(PartialAccessPath ap0, Content f |
partialPathReadStep(mid, ap0, f, node, cc, config) and
apConsFwd(ap, f, ap0, config)
)
@@ -2210,7 +2263,7 @@ private module FlowExploration {
pragma[inline]
private predicate partialPathStoreStep(
PartialPathNodePriv mid, AccessPath ap1, Content f, Node node, AccessPath ap2
PartialPathNodePriv mid, PartialAccessPath ap1, Content f, Node node, PartialAccessPath ap2
) {
ap1 = mid.getAp() and
store(mid.getNode(), f, node) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
}
pragma[nomagic]
private predicate apConsFwd(AccessPath ap1, Content f, AccessPath ap2, Configuration config) {
private predicate apConsFwd(
PartialAccessPath ap1, Content f, PartialAccessPath ap2, Configuration config
) {
exists(PartialPathNodePriv mid |
partialPathStoreStep(mid, ap1, f, _, ap2) and
config = mid.getConfiguration()
@@ -2229,7 +2284,7 @@ private module FlowExploration {
pragma[nomagic]
private predicate partialPathReadStep(
PartialPathNodePriv mid, AccessPath ap, Content f, Node node, CallContext cc,
PartialPathNodePriv mid, PartialAccessPath ap, Content f, Node node, CallContext cc,
Configuration config
) {
ap = mid.getAp() and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable0(
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, AccessPath ap,
PartialPathNodePriv mid, ReturnPosition pos, CallContext innercc, PartialAccessPath ap,
Configuration config
) {
pos = getReturnPosition(mid.getNode()) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathOutOfCallable1(
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
PartialPathNodePriv mid, DataFlowCall call, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc |
partialPathOutOfCallable0(mid, pos, innercc, ap, config) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(ReturnKind kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, cc, ap, config)
@@ -2276,7 +2331,7 @@ private module FlowExploration {
}
private predicate partialPathOutOfArgument(
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, AccessPath ap,
PartialPathNodePriv mid, PostUpdateNode node, CallContext cc, PartialAccessPath ap,
Configuration config
) {
exists(
@@ -2302,7 +2357,7 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodePriv mid, int i, CallContext cc, DataFlowCall call, boolean emptyAp,
AccessPath ap, Configuration config
PartialAccessPath ap, Configuration config
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
@@ -2311,16 +2366,16 @@ private module FlowExploration {
ap = mid.getAp() and
config = mid.getConfiguration()
|
ap instanceof AccessPathNil and emptyAp = true
ap instanceof PartialAccessPathNil and emptyAp = true
or
ap instanceof AccessPathCons and emptyAp = false
ap instanceof PartialAccessPathCons and emptyAp = false
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodePriv mid, DataFlowCallable callable, int i, CallContext outercc,
DataFlowCall call, boolean emptyAp, AccessPath ap, Configuration config
DataFlowCall call, boolean emptyAp, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, emptyAp, ap, config) and
callable = resolveCall(call, outercc)
@@ -2328,7 +2383,7 @@ private module FlowExploration {
private predicate partialPathIntoCallable(
PartialPathNodePriv mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
DataFlowCall call, AccessPath ap, Configuration config
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
exists(int i, DataFlowCallable callable, boolean emptyAp |
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
pragma[nomagic]
private predicate paramFlowsThroughInPartialPath(
ParameterNode p, ReturnKind kind, CallContextCall cc, AccessPathNil apnil, Configuration config
ParameterNode p, ReturnKind kind, CallContextCall cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(PartialPathNodePriv mid, ReturnNode ret |
mid.getNode() = ret and
@@ -2362,9 +2418,9 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
AccessPathNil apnil, Configuration config
PartialAccessPathNil apnil, Configuration config
) {
exists(ParameterNode p, CallContext innercc, AccessPathNil midapnil |
exists(ParameterNode p, CallContext innercc, PartialAccessPathNil midapnil |
partialPathIntoCallable(mid, p, cc, innercc, call, midapnil, config) and
paramFlowsThroughInPartialPath(p, kind, innercc, apnil, config) and
not parameterValueFlowsThrough(p, kind, innercc)
@@ -2372,7 +2428,8 @@ private module FlowExploration {
}
private predicate partialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPathNil apnil, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPathNil apnil,
Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
partialPathThroughCallable0(call, mid, kind, cc, apnil, config) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
pragma[noinline]
private predicate valuePartialPathThroughCallable0(
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc, AccessPath ap,
Configuration config
DataFlowCall call, PartialPathNodePriv mid, ReturnKind kind, CallContext cc,
PartialAccessPath ap, Configuration config
) {
exists(ParameterNode p, CallContext innercc |
partialPathIntoCallable(mid, p, cc, innercc, call, ap, config) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
}
private predicate valuePartialPathThroughCallable(
PartialPathNodePriv mid, OutNode out, CallContext cc, AccessPath ap, Configuration config
PartialPathNodePriv mid, OutNode out, CallContext cc, PartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, ReturnKind kind |
valuePartialPathThroughCallable0(call, mid, kind, cc, ap, config) and