mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Sync.
This commit is contained in:
committed by
Tom Hvitved
parent
b4ecfaeda3
commit
94f110f739
@@ -1645,7 +1645,7 @@ private class AccessPathApproxOption extends TAccessPathApproxOption {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is reachable with approximate access path `ap` from a source
|
||||
* Holds if `node` is reachable with approximate access path `apa` from a source
|
||||
* in the configuration `config`.
|
||||
*
|
||||
* The call context `cc` records whether the node is reached through an
|
||||
@@ -1863,7 +1863,7 @@ private predicate flowFwdIsEntered(
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with approximate access path `ap` is part of a path from a
|
||||
* Holds if `node` with approximate access path `apa` is part of a path from a
|
||||
* source to a sink in the configuration `config`.
|
||||
*
|
||||
* The Boolean `toReturn` records whether the node must be returned from
|
||||
@@ -2098,26 +2098,22 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
||||
|
||||
private newtype TAccessPath =
|
||||
TAccessPathNil(DataFlowType t) or
|
||||
TAccessPathCons(TypedContent head, AccessPath tail) { pathStoreStep(_, _, tail, _, head, _) }
|
||||
TAccessPathCons(TypedContent head, AccessPath tail) { flowConsCand(head, tail.getApprox(), _) }
|
||||
|
||||
private newtype TPathNode =
|
||||
TPathNodeMid(
|
||||
Node node, CallContext cc, SummaryCtx sc, AccessPath ap, AccessPathApprox apa,
|
||||
Configuration config
|
||||
) {
|
||||
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
|
||||
// A PathNode is introduced by a source ...
|
||||
flow(node, config) and
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
ap = TAccessPathNil(getNodeType(node)) and
|
||||
apa = TNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
or
|
||||
// ... or a step from an existing PathNode to another node.
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, cc, sc, ap, apa) and
|
||||
pathStep(mid, node, cc, sc, ap) and
|
||||
config = mid.getConfiguration() and
|
||||
flow(node, _, _, apa, unbind(config))
|
||||
flow(node, _, _, ap.getApprox(), unbind(config))
|
||||
)
|
||||
} or
|
||||
TPathNodeSink(Node node, Configuration config) {
|
||||
@@ -2129,7 +2125,7 @@ private newtype TPathNode =
|
||||
or
|
||||
// ... or a sink that can be reached from a source
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, _, TNil(_)) and
|
||||
pathStep(mid, node, _, _, TAccessPathNil(_)) and
|
||||
config = unbind(mid.getConfiguration())
|
||||
)
|
||||
)
|
||||
@@ -2142,9 +2138,6 @@ private newtype TPathNode =
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
*/
|
||||
abstract private class AccessPath extends TAccessPath {
|
||||
/** Gets the type of this access path. */
|
||||
abstract DataFlowType getType();
|
||||
|
||||
/** Gets the head of this access path, if any. */
|
||||
abstract TypedContent getHead();
|
||||
|
||||
@@ -2178,7 +2171,7 @@ private class AccessPathNil extends AccessPath, TAccessPathNil {
|
||||
|
||||
AccessPathNil() { this = TAccessPathNil(t) }
|
||||
|
||||
override DataFlowType getType() { result = t }
|
||||
DataFlowType getType() { result = t }
|
||||
|
||||
override TypedContent getHead() { none() }
|
||||
|
||||
@@ -2199,8 +2192,6 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
|
||||
AccessPathCons() { this = TAccessPathCons(head, tail) }
|
||||
|
||||
override DataFlowType getType() { result = tail.getType() }
|
||||
|
||||
override TypedContent getHead() { result = head }
|
||||
|
||||
override AccessPath getTail() { result = tail }
|
||||
@@ -2216,14 +2207,16 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
override int length() { result = 1 + tail.length() }
|
||||
|
||||
private string toStringImpl() {
|
||||
tail = TAccessPathNil(_) and
|
||||
result = head.toString()
|
||||
exists(DataFlowType t |
|
||||
tail = TAccessPathNil(t) and
|
||||
result = head.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
or
|
||||
result = head + ", " + tail.(AccessPathCons).toStringImpl()
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl() + "]" + concat(" : " + ppReprType(this.getType()))
|
||||
result = "[" + this.toStringImpl()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2340,10 +2333,9 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
CallContext cc;
|
||||
SummaryCtx sc;
|
||||
AccessPath ap;
|
||||
AccessPathApprox apa;
|
||||
Configuration config;
|
||||
|
||||
PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, apa, config) }
|
||||
PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, config) }
|
||||
|
||||
override Node getNode() { result = node }
|
||||
|
||||
@@ -2353,13 +2345,10 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
AccessPath getAp() { result = ap }
|
||||
|
||||
AccessPathApprox getApa() { result = apa }
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
private PathNodeMid getSuccMid() {
|
||||
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(),
|
||||
result.getAp(), _) and
|
||||
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(), result.getAp()) and
|
||||
result.getConfiguration() = unbind(this.getConfiguration())
|
||||
}
|
||||
|
||||
@@ -2371,7 +2360,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getApa() instanceof AccessPathApproxNil and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
@@ -2381,7 +2370,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
apa instanceof AccessPathApproxNil
|
||||
ap instanceof AccessPathNil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2409,33 +2398,22 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
* Holds if data may flow from `mid` to `node`. The last step in or out of
|
||||
* a callable is recorded by `cc`.
|
||||
*/
|
||||
private predicate pathStep(
|
||||
PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||
pathStepSameAp(mid, node, cc, sc) and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa()
|
||||
ap = mid.getAp()
|
||||
or
|
||||
exists(DataFlowType t |
|
||||
pathStepEmptyAp(mid, node, cc, sc, t) and
|
||||
ap = TAccessPathNil(t) and
|
||||
apa = TNil(t)
|
||||
ap = TAccessPathNil(t)
|
||||
)
|
||||
or
|
||||
exists(TypedContent tc, AccessPathApprox apa0 |
|
||||
pathStoreStep(mid, node, ap.pop(tc), apa0, tc, cc) and
|
||||
// Same as `apa = ap.getApprox()`, but avoids mutual recursion
|
||||
apa0 = apa.pop(tc)
|
||||
) and
|
||||
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx()
|
||||
or
|
||||
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx() and
|
||||
// Here the approximation cannot be created from the approximation before
|
||||
// the read, so we must use `getApprox()`
|
||||
apa = ap.getApprox()
|
||||
sc = mid.getSummaryCtx()
|
||||
or
|
||||
pathThroughCallable(mid, node, cc, ap, apa) and
|
||||
pathThroughCallable(mid, node, cc, ap) and
|
||||
sc = mid.getSummaryCtx()
|
||||
}
|
||||
|
||||
@@ -2504,10 +2482,9 @@ private predicate storeCand(Node node1, TypedContent tc, Node node2, Configurati
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate pathStoreStep(
|
||||
PathNodeMid mid, Node node, AccessPath ap0, AccessPathApprox apa0, TypedContent tc, CallContext cc
|
||||
PathNodeMid mid, Node node, AccessPath ap0, TypedContent tc, CallContext cc
|
||||
) {
|
||||
ap0 = mid.getAp() and
|
||||
apa0 = mid.getApa() and
|
||||
storeCand(mid.getNode(), tc, node, mid.getConfiguration()) and
|
||||
cc = mid.getCallContext()
|
||||
}
|
||||
@@ -2519,7 +2496,7 @@ private predicate pathOutOfCallable0(
|
||||
pos = getReturnPosition(mid.getNode()) and
|
||||
innercc = mid.getCallContext() and
|
||||
innercc instanceof CallContextNoCall and
|
||||
apa = mid.getApa() and
|
||||
apa = mid.getAp().getApprox() and
|
||||
config = mid.getConfiguration()
|
||||
}
|
||||
|
||||
@@ -2570,7 +2547,7 @@ private predicate pathIntoArg(
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa()
|
||||
apa = ap.getApprox()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2653,7 +2630,7 @@ private predicate paramFlowsThrough(
|
||||
sc = mid.getSummaryCtx() and
|
||||
config = mid.getConfiguration() and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
@@ -2675,10 +2652,8 @@ private predicate pathThroughCallable0(
|
||||
* The context `cc` is restored to its value prior to entering the callable.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate pathThroughCallable(
|
||||
PathNodeMid mid, Node out, CallContext cc, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt kind |
|
||||
private predicate pathThroughCallable(PathNodeMid mid, Node out, CallContext cc, AccessPath ap) {
|
||||
exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
|
||||
pathThroughCallable0(call, mid, kind, cc, ap, apa) and
|
||||
out = getAnOutNodeFlow(kind, call, apa, unbind(mid.getConfiguration()))
|
||||
)
|
||||
|
||||
@@ -1645,7 +1645,7 @@ private class AccessPathApproxOption extends TAccessPathApproxOption {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is reachable with approximate access path `ap` from a source
|
||||
* Holds if `node` is reachable with approximate access path `apa` from a source
|
||||
* in the configuration `config`.
|
||||
*
|
||||
* The call context `cc` records whether the node is reached through an
|
||||
@@ -1863,7 +1863,7 @@ private predicate flowFwdIsEntered(
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with approximate access path `ap` is part of a path from a
|
||||
* Holds if `node` with approximate access path `apa` is part of a path from a
|
||||
* source to a sink in the configuration `config`.
|
||||
*
|
||||
* The Boolean `toReturn` records whether the node must be returned from
|
||||
@@ -2098,26 +2098,22 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
||||
|
||||
private newtype TAccessPath =
|
||||
TAccessPathNil(DataFlowType t) or
|
||||
TAccessPathCons(TypedContent head, AccessPath tail) { pathStoreStep(_, _, tail, _, head, _) }
|
||||
TAccessPathCons(TypedContent head, AccessPath tail) { flowConsCand(head, tail.getApprox(), _) }
|
||||
|
||||
private newtype TPathNode =
|
||||
TPathNodeMid(
|
||||
Node node, CallContext cc, SummaryCtx sc, AccessPath ap, AccessPathApprox apa,
|
||||
Configuration config
|
||||
) {
|
||||
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
|
||||
// A PathNode is introduced by a source ...
|
||||
flow(node, config) and
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
ap = TAccessPathNil(getNodeType(node)) and
|
||||
apa = TNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
or
|
||||
// ... or a step from an existing PathNode to another node.
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, cc, sc, ap, apa) and
|
||||
pathStep(mid, node, cc, sc, ap) and
|
||||
config = mid.getConfiguration() and
|
||||
flow(node, _, _, apa, unbind(config))
|
||||
flow(node, _, _, ap.getApprox(), unbind(config))
|
||||
)
|
||||
} or
|
||||
TPathNodeSink(Node node, Configuration config) {
|
||||
@@ -2129,7 +2125,7 @@ private newtype TPathNode =
|
||||
or
|
||||
// ... or a sink that can be reached from a source
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, _, TNil(_)) and
|
||||
pathStep(mid, node, _, _, TAccessPathNil(_)) and
|
||||
config = unbind(mid.getConfiguration())
|
||||
)
|
||||
)
|
||||
@@ -2142,9 +2138,6 @@ private newtype TPathNode =
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
*/
|
||||
abstract private class AccessPath extends TAccessPath {
|
||||
/** Gets the type of this access path. */
|
||||
abstract DataFlowType getType();
|
||||
|
||||
/** Gets the head of this access path, if any. */
|
||||
abstract TypedContent getHead();
|
||||
|
||||
@@ -2178,7 +2171,7 @@ private class AccessPathNil extends AccessPath, TAccessPathNil {
|
||||
|
||||
AccessPathNil() { this = TAccessPathNil(t) }
|
||||
|
||||
override DataFlowType getType() { result = t }
|
||||
DataFlowType getType() { result = t }
|
||||
|
||||
override TypedContent getHead() { none() }
|
||||
|
||||
@@ -2199,8 +2192,6 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
|
||||
AccessPathCons() { this = TAccessPathCons(head, tail) }
|
||||
|
||||
override DataFlowType getType() { result = tail.getType() }
|
||||
|
||||
override TypedContent getHead() { result = head }
|
||||
|
||||
override AccessPath getTail() { result = tail }
|
||||
@@ -2216,14 +2207,16 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
override int length() { result = 1 + tail.length() }
|
||||
|
||||
private string toStringImpl() {
|
||||
tail = TAccessPathNil(_) and
|
||||
result = head.toString()
|
||||
exists(DataFlowType t |
|
||||
tail = TAccessPathNil(t) and
|
||||
result = head.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
or
|
||||
result = head + ", " + tail.(AccessPathCons).toStringImpl()
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl() + "]" + concat(" : " + ppReprType(this.getType()))
|
||||
result = "[" + this.toStringImpl()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2340,10 +2333,9 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
CallContext cc;
|
||||
SummaryCtx sc;
|
||||
AccessPath ap;
|
||||
AccessPathApprox apa;
|
||||
Configuration config;
|
||||
|
||||
PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, apa, config) }
|
||||
PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, config) }
|
||||
|
||||
override Node getNode() { result = node }
|
||||
|
||||
@@ -2353,13 +2345,10 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
AccessPath getAp() { result = ap }
|
||||
|
||||
AccessPathApprox getApa() { result = apa }
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
private PathNodeMid getSuccMid() {
|
||||
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(),
|
||||
result.getAp(), _) and
|
||||
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(), result.getAp()) and
|
||||
result.getConfiguration() = unbind(this.getConfiguration())
|
||||
}
|
||||
|
||||
@@ -2371,7 +2360,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getApa() instanceof AccessPathApproxNil and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
@@ -2381,7 +2370,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
apa instanceof AccessPathApproxNil
|
||||
ap instanceof AccessPathNil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2409,33 +2398,22 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
* Holds if data may flow from `mid` to `node`. The last step in or out of
|
||||
* a callable is recorded by `cc`.
|
||||
*/
|
||||
private predicate pathStep(
|
||||
PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||
pathStepSameAp(mid, node, cc, sc) and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa()
|
||||
ap = mid.getAp()
|
||||
or
|
||||
exists(DataFlowType t |
|
||||
pathStepEmptyAp(mid, node, cc, sc, t) and
|
||||
ap = TAccessPathNil(t) and
|
||||
apa = TNil(t)
|
||||
ap = TAccessPathNil(t)
|
||||
)
|
||||
or
|
||||
exists(TypedContent tc, AccessPathApprox apa0 |
|
||||
pathStoreStep(mid, node, ap.pop(tc), apa0, tc, cc) and
|
||||
// Same as `apa = ap.getApprox()`, but avoids mutual recursion
|
||||
apa0 = apa.pop(tc)
|
||||
) and
|
||||
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx()
|
||||
or
|
||||
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx() and
|
||||
// Here the approximation cannot be created from the approximation before
|
||||
// the read, so we must use `getApprox()`
|
||||
apa = ap.getApprox()
|
||||
sc = mid.getSummaryCtx()
|
||||
or
|
||||
pathThroughCallable(mid, node, cc, ap, apa) and
|
||||
pathThroughCallable(mid, node, cc, ap) and
|
||||
sc = mid.getSummaryCtx()
|
||||
}
|
||||
|
||||
@@ -2504,10 +2482,9 @@ private predicate storeCand(Node node1, TypedContent tc, Node node2, Configurati
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate pathStoreStep(
|
||||
PathNodeMid mid, Node node, AccessPath ap0, AccessPathApprox apa0, TypedContent tc, CallContext cc
|
||||
PathNodeMid mid, Node node, AccessPath ap0, TypedContent tc, CallContext cc
|
||||
) {
|
||||
ap0 = mid.getAp() and
|
||||
apa0 = mid.getApa() and
|
||||
storeCand(mid.getNode(), tc, node, mid.getConfiguration()) and
|
||||
cc = mid.getCallContext()
|
||||
}
|
||||
@@ -2519,7 +2496,7 @@ private predicate pathOutOfCallable0(
|
||||
pos = getReturnPosition(mid.getNode()) and
|
||||
innercc = mid.getCallContext() and
|
||||
innercc instanceof CallContextNoCall and
|
||||
apa = mid.getApa() and
|
||||
apa = mid.getAp().getApprox() and
|
||||
config = mid.getConfiguration()
|
||||
}
|
||||
|
||||
@@ -2570,7 +2547,7 @@ private predicate pathIntoArg(
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa()
|
||||
apa = ap.getApprox()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2653,7 +2630,7 @@ private predicate paramFlowsThrough(
|
||||
sc = mid.getSummaryCtx() and
|
||||
config = mid.getConfiguration() and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
@@ -2675,10 +2652,8 @@ private predicate pathThroughCallable0(
|
||||
* The context `cc` is restored to its value prior to entering the callable.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate pathThroughCallable(
|
||||
PathNodeMid mid, Node out, CallContext cc, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt kind |
|
||||
private predicate pathThroughCallable(PathNodeMid mid, Node out, CallContext cc, AccessPath ap) {
|
||||
exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
|
||||
pathThroughCallable0(call, mid, kind, cc, ap, apa) and
|
||||
out = getAnOutNodeFlow(kind, call, apa, unbind(mid.getConfiguration()))
|
||||
)
|
||||
|
||||
@@ -1645,7 +1645,7 @@ private class AccessPathApproxOption extends TAccessPathApproxOption {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is reachable with approximate access path `ap` from a source
|
||||
* Holds if `node` is reachable with approximate access path `apa` from a source
|
||||
* in the configuration `config`.
|
||||
*
|
||||
* The call context `cc` records whether the node is reached through an
|
||||
@@ -1863,7 +1863,7 @@ private predicate flowFwdIsEntered(
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with approximate access path `ap` is part of a path from a
|
||||
* Holds if `node` with approximate access path `apa` is part of a path from a
|
||||
* source to a sink in the configuration `config`.
|
||||
*
|
||||
* The Boolean `toReturn` records whether the node must be returned from
|
||||
@@ -2098,26 +2098,22 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
||||
|
||||
private newtype TAccessPath =
|
||||
TAccessPathNil(DataFlowType t) or
|
||||
TAccessPathCons(TypedContent head, AccessPath tail) { pathStoreStep(_, _, tail, _, head, _) }
|
||||
TAccessPathCons(TypedContent head, AccessPath tail) { flowConsCand(head, tail.getApprox(), _) }
|
||||
|
||||
private newtype TPathNode =
|
||||
TPathNodeMid(
|
||||
Node node, CallContext cc, SummaryCtx sc, AccessPath ap, AccessPathApprox apa,
|
||||
Configuration config
|
||||
) {
|
||||
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
|
||||
// A PathNode is introduced by a source ...
|
||||
flow(node, config) and
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
ap = TAccessPathNil(getNodeType(node)) and
|
||||
apa = TNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
or
|
||||
// ... or a step from an existing PathNode to another node.
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, cc, sc, ap, apa) and
|
||||
pathStep(mid, node, cc, sc, ap) and
|
||||
config = mid.getConfiguration() and
|
||||
flow(node, _, _, apa, unbind(config))
|
||||
flow(node, _, _, ap.getApprox(), unbind(config))
|
||||
)
|
||||
} or
|
||||
TPathNodeSink(Node node, Configuration config) {
|
||||
@@ -2129,7 +2125,7 @@ private newtype TPathNode =
|
||||
or
|
||||
// ... or a sink that can be reached from a source
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, _, TNil(_)) and
|
||||
pathStep(mid, node, _, _, TAccessPathNil(_)) and
|
||||
config = unbind(mid.getConfiguration())
|
||||
)
|
||||
)
|
||||
@@ -2142,9 +2138,6 @@ private newtype TPathNode =
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
*/
|
||||
abstract private class AccessPath extends TAccessPath {
|
||||
/** Gets the type of this access path. */
|
||||
abstract DataFlowType getType();
|
||||
|
||||
/** Gets the head of this access path, if any. */
|
||||
abstract TypedContent getHead();
|
||||
|
||||
@@ -2178,7 +2171,7 @@ private class AccessPathNil extends AccessPath, TAccessPathNil {
|
||||
|
||||
AccessPathNil() { this = TAccessPathNil(t) }
|
||||
|
||||
override DataFlowType getType() { result = t }
|
||||
DataFlowType getType() { result = t }
|
||||
|
||||
override TypedContent getHead() { none() }
|
||||
|
||||
@@ -2199,8 +2192,6 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
|
||||
AccessPathCons() { this = TAccessPathCons(head, tail) }
|
||||
|
||||
override DataFlowType getType() { result = tail.getType() }
|
||||
|
||||
override TypedContent getHead() { result = head }
|
||||
|
||||
override AccessPath getTail() { result = tail }
|
||||
@@ -2216,14 +2207,16 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
override int length() { result = 1 + tail.length() }
|
||||
|
||||
private string toStringImpl() {
|
||||
tail = TAccessPathNil(_) and
|
||||
result = head.toString()
|
||||
exists(DataFlowType t |
|
||||
tail = TAccessPathNil(t) and
|
||||
result = head.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
or
|
||||
result = head + ", " + tail.(AccessPathCons).toStringImpl()
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl() + "]" + concat(" : " + ppReprType(this.getType()))
|
||||
result = "[" + this.toStringImpl()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2340,10 +2333,9 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
CallContext cc;
|
||||
SummaryCtx sc;
|
||||
AccessPath ap;
|
||||
AccessPathApprox apa;
|
||||
Configuration config;
|
||||
|
||||
PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, apa, config) }
|
||||
PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, config) }
|
||||
|
||||
override Node getNode() { result = node }
|
||||
|
||||
@@ -2353,13 +2345,10 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
AccessPath getAp() { result = ap }
|
||||
|
||||
AccessPathApprox getApa() { result = apa }
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
private PathNodeMid getSuccMid() {
|
||||
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(),
|
||||
result.getAp(), _) and
|
||||
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(), result.getAp()) and
|
||||
result.getConfiguration() = unbind(this.getConfiguration())
|
||||
}
|
||||
|
||||
@@ -2371,7 +2360,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getApa() instanceof AccessPathApproxNil and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
@@ -2381,7 +2370,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
apa instanceof AccessPathApproxNil
|
||||
ap instanceof AccessPathNil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2409,33 +2398,22 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
* Holds if data may flow from `mid` to `node`. The last step in or out of
|
||||
* a callable is recorded by `cc`.
|
||||
*/
|
||||
private predicate pathStep(
|
||||
PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||
pathStepSameAp(mid, node, cc, sc) and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa()
|
||||
ap = mid.getAp()
|
||||
or
|
||||
exists(DataFlowType t |
|
||||
pathStepEmptyAp(mid, node, cc, sc, t) and
|
||||
ap = TAccessPathNil(t) and
|
||||
apa = TNil(t)
|
||||
ap = TAccessPathNil(t)
|
||||
)
|
||||
or
|
||||
exists(TypedContent tc, AccessPathApprox apa0 |
|
||||
pathStoreStep(mid, node, ap.pop(tc), apa0, tc, cc) and
|
||||
// Same as `apa = ap.getApprox()`, but avoids mutual recursion
|
||||
apa0 = apa.pop(tc)
|
||||
) and
|
||||
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx()
|
||||
or
|
||||
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx() and
|
||||
// Here the approximation cannot be created from the approximation before
|
||||
// the read, so we must use `getApprox()`
|
||||
apa = ap.getApprox()
|
||||
sc = mid.getSummaryCtx()
|
||||
or
|
||||
pathThroughCallable(mid, node, cc, ap, apa) and
|
||||
pathThroughCallable(mid, node, cc, ap) and
|
||||
sc = mid.getSummaryCtx()
|
||||
}
|
||||
|
||||
@@ -2504,10 +2482,9 @@ private predicate storeCand(Node node1, TypedContent tc, Node node2, Configurati
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate pathStoreStep(
|
||||
PathNodeMid mid, Node node, AccessPath ap0, AccessPathApprox apa0, TypedContent tc, CallContext cc
|
||||
PathNodeMid mid, Node node, AccessPath ap0, TypedContent tc, CallContext cc
|
||||
) {
|
||||
ap0 = mid.getAp() and
|
||||
apa0 = mid.getApa() and
|
||||
storeCand(mid.getNode(), tc, node, mid.getConfiguration()) and
|
||||
cc = mid.getCallContext()
|
||||
}
|
||||
@@ -2519,7 +2496,7 @@ private predicate pathOutOfCallable0(
|
||||
pos = getReturnPosition(mid.getNode()) and
|
||||
innercc = mid.getCallContext() and
|
||||
innercc instanceof CallContextNoCall and
|
||||
apa = mid.getApa() and
|
||||
apa = mid.getAp().getApprox() and
|
||||
config = mid.getConfiguration()
|
||||
}
|
||||
|
||||
@@ -2570,7 +2547,7 @@ private predicate pathIntoArg(
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa()
|
||||
apa = ap.getApprox()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2653,7 +2630,7 @@ private predicate paramFlowsThrough(
|
||||
sc = mid.getSummaryCtx() and
|
||||
config = mid.getConfiguration() and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
@@ -2675,10 +2652,8 @@ private predicate pathThroughCallable0(
|
||||
* The context `cc` is restored to its value prior to entering the callable.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate pathThroughCallable(
|
||||
PathNodeMid mid, Node out, CallContext cc, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt kind |
|
||||
private predicate pathThroughCallable(PathNodeMid mid, Node out, CallContext cc, AccessPath ap) {
|
||||
exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
|
||||
pathThroughCallable0(call, mid, kind, cc, ap, apa) and
|
||||
out = getAnOutNodeFlow(kind, call, apa, unbind(mid.getConfiguration()))
|
||||
)
|
||||
|
||||
@@ -1645,7 +1645,7 @@ private class AccessPathApproxOption extends TAccessPathApproxOption {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is reachable with approximate access path `ap` from a source
|
||||
* Holds if `node` is reachable with approximate access path `apa` from a source
|
||||
* in the configuration `config`.
|
||||
*
|
||||
* The call context `cc` records whether the node is reached through an
|
||||
@@ -1863,7 +1863,7 @@ private predicate flowFwdIsEntered(
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with approximate access path `ap` is part of a path from a
|
||||
* Holds if `node` with approximate access path `apa` is part of a path from a
|
||||
* source to a sink in the configuration `config`.
|
||||
*
|
||||
* The Boolean `toReturn` records whether the node must be returned from
|
||||
@@ -2098,26 +2098,22 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
||||
|
||||
private newtype TAccessPath =
|
||||
TAccessPathNil(DataFlowType t) or
|
||||
TAccessPathCons(TypedContent head, AccessPath tail) { pathStoreStep(_, _, tail, _, head, _) }
|
||||
TAccessPathCons(TypedContent head, AccessPath tail) { flowConsCand(head, tail.getApprox(), _) }
|
||||
|
||||
private newtype TPathNode =
|
||||
TPathNodeMid(
|
||||
Node node, CallContext cc, SummaryCtx sc, AccessPath ap, AccessPathApprox apa,
|
||||
Configuration config
|
||||
) {
|
||||
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
|
||||
// A PathNode is introduced by a source ...
|
||||
flow(node, config) and
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
ap = TAccessPathNil(getNodeType(node)) and
|
||||
apa = TNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
or
|
||||
// ... or a step from an existing PathNode to another node.
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, cc, sc, ap, apa) and
|
||||
pathStep(mid, node, cc, sc, ap) and
|
||||
config = mid.getConfiguration() and
|
||||
flow(node, _, _, apa, unbind(config))
|
||||
flow(node, _, _, ap.getApprox(), unbind(config))
|
||||
)
|
||||
} or
|
||||
TPathNodeSink(Node node, Configuration config) {
|
||||
@@ -2129,7 +2125,7 @@ private newtype TPathNode =
|
||||
or
|
||||
// ... or a sink that can be reached from a source
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, _, TNil(_)) and
|
||||
pathStep(mid, node, _, _, TAccessPathNil(_)) and
|
||||
config = unbind(mid.getConfiguration())
|
||||
)
|
||||
)
|
||||
@@ -2142,9 +2138,6 @@ private newtype TPathNode =
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
*/
|
||||
abstract private class AccessPath extends TAccessPath {
|
||||
/** Gets the type of this access path. */
|
||||
abstract DataFlowType getType();
|
||||
|
||||
/** Gets the head of this access path, if any. */
|
||||
abstract TypedContent getHead();
|
||||
|
||||
@@ -2178,7 +2171,7 @@ private class AccessPathNil extends AccessPath, TAccessPathNil {
|
||||
|
||||
AccessPathNil() { this = TAccessPathNil(t) }
|
||||
|
||||
override DataFlowType getType() { result = t }
|
||||
DataFlowType getType() { result = t }
|
||||
|
||||
override TypedContent getHead() { none() }
|
||||
|
||||
@@ -2199,8 +2192,6 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
|
||||
AccessPathCons() { this = TAccessPathCons(head, tail) }
|
||||
|
||||
override DataFlowType getType() { result = tail.getType() }
|
||||
|
||||
override TypedContent getHead() { result = head }
|
||||
|
||||
override AccessPath getTail() { result = tail }
|
||||
@@ -2216,14 +2207,16 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
override int length() { result = 1 + tail.length() }
|
||||
|
||||
private string toStringImpl() {
|
||||
tail = TAccessPathNil(_) and
|
||||
result = head.toString()
|
||||
exists(DataFlowType t |
|
||||
tail = TAccessPathNil(t) and
|
||||
result = head.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
or
|
||||
result = head + ", " + tail.(AccessPathCons).toStringImpl()
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl() + "]" + concat(" : " + ppReprType(this.getType()))
|
||||
result = "[" + this.toStringImpl()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2340,10 +2333,9 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
CallContext cc;
|
||||
SummaryCtx sc;
|
||||
AccessPath ap;
|
||||
AccessPathApprox apa;
|
||||
Configuration config;
|
||||
|
||||
PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, apa, config) }
|
||||
PathNodeMid() { this = TPathNodeMid(node, cc, sc, ap, config) }
|
||||
|
||||
override Node getNode() { result = node }
|
||||
|
||||
@@ -2353,13 +2345,10 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
AccessPath getAp() { result = ap }
|
||||
|
||||
AccessPathApprox getApa() { result = apa }
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
private PathNodeMid getSuccMid() {
|
||||
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(),
|
||||
result.getAp(), _) and
|
||||
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(), result.getAp()) and
|
||||
result.getConfiguration() = unbind(this.getConfiguration())
|
||||
}
|
||||
|
||||
@@ -2371,7 +2360,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getApa() instanceof AccessPathApproxNil and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbind(mid.getConfiguration()) and
|
||||
result = sink
|
||||
)
|
||||
@@ -2381,7 +2370,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
apa instanceof AccessPathApproxNil
|
||||
ap instanceof AccessPathNil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2409,33 +2398,22 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
* Holds if data may flow from `mid` to `node`. The last step in or out of
|
||||
* a callable is recorded by `cc`.
|
||||
*/
|
||||
private predicate pathStep(
|
||||
PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||
pathStepSameAp(mid, node, cc, sc) and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa()
|
||||
ap = mid.getAp()
|
||||
or
|
||||
exists(DataFlowType t |
|
||||
pathStepEmptyAp(mid, node, cc, sc, t) and
|
||||
ap = TAccessPathNil(t) and
|
||||
apa = TNil(t)
|
||||
ap = TAccessPathNil(t)
|
||||
)
|
||||
or
|
||||
exists(TypedContent tc, AccessPathApprox apa0 |
|
||||
pathStoreStep(mid, node, ap.pop(tc), apa0, tc, cc) and
|
||||
// Same as `apa = ap.getApprox()`, but avoids mutual recursion
|
||||
apa0 = apa.pop(tc)
|
||||
) and
|
||||
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx()
|
||||
or
|
||||
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx() and
|
||||
// Here the approximation cannot be created from the approximation before
|
||||
// the read, so we must use `getApprox()`
|
||||
apa = ap.getApprox()
|
||||
sc = mid.getSummaryCtx()
|
||||
or
|
||||
pathThroughCallable(mid, node, cc, ap, apa) and
|
||||
pathThroughCallable(mid, node, cc, ap) and
|
||||
sc = mid.getSummaryCtx()
|
||||
}
|
||||
|
||||
@@ -2504,10 +2482,9 @@ private predicate storeCand(Node node1, TypedContent tc, Node node2, Configurati
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate pathStoreStep(
|
||||
PathNodeMid mid, Node node, AccessPath ap0, AccessPathApprox apa0, TypedContent tc, CallContext cc
|
||||
PathNodeMid mid, Node node, AccessPath ap0, TypedContent tc, CallContext cc
|
||||
) {
|
||||
ap0 = mid.getAp() and
|
||||
apa0 = mid.getApa() and
|
||||
storeCand(mid.getNode(), tc, node, mid.getConfiguration()) and
|
||||
cc = mid.getCallContext()
|
||||
}
|
||||
@@ -2519,7 +2496,7 @@ private predicate pathOutOfCallable0(
|
||||
pos = getReturnPosition(mid.getNode()) and
|
||||
innercc = mid.getCallContext() and
|
||||
innercc instanceof CallContextNoCall and
|
||||
apa = mid.getApa() and
|
||||
apa = mid.getAp().getApprox() and
|
||||
config = mid.getConfiguration()
|
||||
}
|
||||
|
||||
@@ -2570,7 +2547,7 @@ private predicate pathIntoArg(
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa()
|
||||
apa = ap.getApprox()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2653,7 +2630,7 @@ private predicate paramFlowsThrough(
|
||||
sc = mid.getSummaryCtx() and
|
||||
config = mid.getConfiguration() and
|
||||
ap = mid.getAp() and
|
||||
apa = mid.getApa() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
@@ -2675,10 +2652,8 @@ private predicate pathThroughCallable0(
|
||||
* The context `cc` is restored to its value prior to entering the callable.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate pathThroughCallable(
|
||||
PathNodeMid mid, Node out, CallContext cc, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt kind |
|
||||
private predicate pathThroughCallable(PathNodeMid mid, Node out, CallContext cc, AccessPath ap) {
|
||||
exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
|
||||
pathThroughCallable0(call, mid, kind, cc, ap, apa) and
|
||||
out = getAnOutNodeFlow(kind, call, apa, unbind(mid.getConfiguration()))
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user