Data flow: Sync files

This commit is contained in:
Tom Hvitved
2020-02-17 10:45:35 +01:00
parent bc6c4744b1
commit 28307399f8
18 changed files with 612 additions and 1260 deletions

View File

@@ -1647,9 +1647,6 @@ abstract private class AccessPath extends TAccessPath {
* Holds if this access path has `head` at the front and may be followed by `tail`.
*/
abstract predicate pop(Content head, AccessPath tail);
/** Gets the untyped version of this access path. */
UntypedAccessPath getUntyped() { result.getATyped() = this }
}
private class AccessPathNil extends AccessPath, TNil {
@@ -2001,50 +1998,10 @@ private Configuration unbind(Configuration conf) { result >= conf and result <=
private predicate flow(Node n, Configuration config) { flow(TNormalNode(n), _, _, config) }
private newtype TUntypedAccessPath =
TNilUntyped() or
TConsNilUntyped(Content f) { exists(TConsNil(f, _)) } or
TConsConsUntyped(Content f1, Content f2, int len) { exists(TConsCons(f1, f2, len)) }
/**
* An untyped access path.
*
* Untyped access paths are only used when reconstructing flow summaries,
* where the extra type information is redundant.
*/
private class UntypedAccessPath extends TUntypedAccessPath {
/** Gets a typed version of this untyped access path. */
AccessPath getATyped() {
this = TNilUntyped() and result = TNil(_)
or
exists(Content f | this = TConsNilUntyped(f) | result = TConsNil(f, _))
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
result = TConsCons(f1, f2, len)
)
}
string toString() {
this = TNilUntyped() and
result = "<nil>"
or
exists(Content f | this = TConsNilUntyped(f) | result = "[" + f + "]")
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
if len = 2
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
)
}
}
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, UntypedAccessPath uap) {
exists(ReturnNodeExt ret, Configuration config, AccessPath ap |
ap = uap.getATyped() and
flow(TNormalNode(p), true, ap, config)
|
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
exists(ReturnNodeExt ret, Configuration config | flow(TNormalNode(p), true, ap, config) |
exists(Summary summary |
parameterFlowReturn(p, ret, _, _, _, summary, config) and
flow(ret, unbind(config))
@@ -2080,12 +2037,30 @@ private newtype TSummaryCtx =
*
* Summaries are only created for parameters that may flow through.
*/
private class SummaryCtx extends TSummaryCtx {
string toString() { result = "SummaryCtx" }
abstract private class SummaryCtx extends TSummaryCtx {
abstract string toString();
}
/** A summary context from which no flow summary can be generated. */
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { }
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
override string toString() { result = "<none>" }
}
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
p.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private newtype TPathNode =
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
@@ -2399,22 +2374,22 @@ private predicate pathOutOfCallable(PathNodeMid mid, Node out, CallContext cc) {
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, UntypedAccessPath ap
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp().getUntyped()
ap = mid.getAp()
)
}
pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, UntypedAccessPath ap, Configuration config
DataFlowCallable callable, int i, AccessPath ap, Configuration config
) {
exists(ParameterNode p |
flow(TNormalNode(p), _, ap.getATyped(), config) and
flow(TNormalNode(p), _, ap, config) and
p.isParameterOf(callable, i)
)
}
@@ -2422,7 +2397,7 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
UntypedAccessPath ap
AccessPath ap
) {
pathIntoArg(mid, i, outercc, call, ap) and
callable = resolveCall(call, outercc) and
@@ -2438,7 +2413,7 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, UntypedAccessPath ap |
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap) and
p.isParameterOf(callable, i) and
(
@@ -2457,7 +2432,7 @@ private predicate pathIntoCallable(
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
pragma[nomagic]
private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, TSummaryCtxSome sc, AccessPath ap, Configuration config
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, Configuration config
) {
exists(PathNodeMid mid, ReturnNodeExt ret |
mid.getNode() = ret and
@@ -2635,14 +2610,7 @@ private module FlowExploration {
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
TSummaryCtx2Nil() or
TSummaryCtx2ConsNil(Content f)
private TSummaryCtx2 getSummaryCtx2(PartialAccessPath ap) {
result = TSummaryCtx2Nil() and ap instanceof PartialAccessPathNil
or
exists(Content f | result = TSummaryCtx2ConsNil(f) and ap = TPartialCons(f, 1))
}
TSummaryCtx2Some(PartialAccessPath ap)
private newtype TPartialPathNode =
TPartialPathNodeMk(
@@ -2929,11 +2897,8 @@ private module FlowExploration {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc1 = TSummaryCtx1Param(p) and sc2 = getSummaryCtx2(ap)
or
sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and not exists(getSummaryCtx2(ap))
)
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
if recordDataFlowCallSite(call, callable)
then innercc = TSpecificCall(call)
@@ -2953,8 +2918,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
config = mid.getConfiguration() and
ap = mid.getAp() and
ap.len() in [0 .. 1]
ap = mid.getAp()
)
}

View File

@@ -1647,9 +1647,6 @@ abstract private class AccessPath extends TAccessPath {
* Holds if this access path has `head` at the front and may be followed by `tail`.
*/
abstract predicate pop(Content head, AccessPath tail);
/** Gets the untyped version of this access path. */
UntypedAccessPath getUntyped() { result.getATyped() = this }
}
private class AccessPathNil extends AccessPath, TNil {
@@ -2001,50 +1998,10 @@ private Configuration unbind(Configuration conf) { result >= conf and result <=
private predicate flow(Node n, Configuration config) { flow(TNormalNode(n), _, _, config) }
private newtype TUntypedAccessPath =
TNilUntyped() or
TConsNilUntyped(Content f) { exists(TConsNil(f, _)) } or
TConsConsUntyped(Content f1, Content f2, int len) { exists(TConsCons(f1, f2, len)) }
/**
* An untyped access path.
*
* Untyped access paths are only used when reconstructing flow summaries,
* where the extra type information is redundant.
*/
private class UntypedAccessPath extends TUntypedAccessPath {
/** Gets a typed version of this untyped access path. */
AccessPath getATyped() {
this = TNilUntyped() and result = TNil(_)
or
exists(Content f | this = TConsNilUntyped(f) | result = TConsNil(f, _))
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
result = TConsCons(f1, f2, len)
)
}
string toString() {
this = TNilUntyped() and
result = "<nil>"
or
exists(Content f | this = TConsNilUntyped(f) | result = "[" + f + "]")
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
if len = 2
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
)
}
}
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, UntypedAccessPath uap) {
exists(ReturnNodeExt ret, Configuration config, AccessPath ap |
ap = uap.getATyped() and
flow(TNormalNode(p), true, ap, config)
|
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
exists(ReturnNodeExt ret, Configuration config | flow(TNormalNode(p), true, ap, config) |
exists(Summary summary |
parameterFlowReturn(p, ret, _, _, _, summary, config) and
flow(ret, unbind(config))
@@ -2080,12 +2037,30 @@ private newtype TSummaryCtx =
*
* Summaries are only created for parameters that may flow through.
*/
private class SummaryCtx extends TSummaryCtx {
string toString() { result = "SummaryCtx" }
abstract private class SummaryCtx extends TSummaryCtx {
abstract string toString();
}
/** A summary context from which no flow summary can be generated. */
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { }
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
override string toString() { result = "<none>" }
}
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
p.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private newtype TPathNode =
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
@@ -2399,22 +2374,22 @@ private predicate pathOutOfCallable(PathNodeMid mid, Node out, CallContext cc) {
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, UntypedAccessPath ap
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp().getUntyped()
ap = mid.getAp()
)
}
pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, UntypedAccessPath ap, Configuration config
DataFlowCallable callable, int i, AccessPath ap, Configuration config
) {
exists(ParameterNode p |
flow(TNormalNode(p), _, ap.getATyped(), config) and
flow(TNormalNode(p), _, ap, config) and
p.isParameterOf(callable, i)
)
}
@@ -2422,7 +2397,7 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
UntypedAccessPath ap
AccessPath ap
) {
pathIntoArg(mid, i, outercc, call, ap) and
callable = resolveCall(call, outercc) and
@@ -2438,7 +2413,7 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, UntypedAccessPath ap |
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap) and
p.isParameterOf(callable, i) and
(
@@ -2457,7 +2432,7 @@ private predicate pathIntoCallable(
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
pragma[nomagic]
private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, TSummaryCtxSome sc, AccessPath ap, Configuration config
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, Configuration config
) {
exists(PathNodeMid mid, ReturnNodeExt ret |
mid.getNode() = ret and
@@ -2635,14 +2610,7 @@ private module FlowExploration {
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
TSummaryCtx2Nil() or
TSummaryCtx2ConsNil(Content f)
private TSummaryCtx2 getSummaryCtx2(PartialAccessPath ap) {
result = TSummaryCtx2Nil() and ap instanceof PartialAccessPathNil
or
exists(Content f | result = TSummaryCtx2ConsNil(f) and ap = TPartialCons(f, 1))
}
TSummaryCtx2Some(PartialAccessPath ap)
private newtype TPartialPathNode =
TPartialPathNodeMk(
@@ -2929,11 +2897,8 @@ private module FlowExploration {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc1 = TSummaryCtx1Param(p) and sc2 = getSummaryCtx2(ap)
or
sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and not exists(getSummaryCtx2(ap))
)
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
if recordDataFlowCallSite(call, callable)
then innercc = TSpecificCall(call)
@@ -2953,8 +2918,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
config = mid.getConfiguration() and
ap = mid.getAp() and
ap.len() in [0 .. 1]
ap = mid.getAp()
)
}

View File

@@ -1647,9 +1647,6 @@ abstract private class AccessPath extends TAccessPath {
* Holds if this access path has `head` at the front and may be followed by `tail`.
*/
abstract predicate pop(Content head, AccessPath tail);
/** Gets the untyped version of this access path. */
UntypedAccessPath getUntyped() { result.getATyped() = this }
}
private class AccessPathNil extends AccessPath, TNil {
@@ -2001,50 +1998,10 @@ private Configuration unbind(Configuration conf) { result >= conf and result <=
private predicate flow(Node n, Configuration config) { flow(TNormalNode(n), _, _, config) }
private newtype TUntypedAccessPath =
TNilUntyped() or
TConsNilUntyped(Content f) { exists(TConsNil(f, _)) } or
TConsConsUntyped(Content f1, Content f2, int len) { exists(TConsCons(f1, f2, len)) }
/**
* An untyped access path.
*
* Untyped access paths are only used when reconstructing flow summaries,
* where the extra type information is redundant.
*/
private class UntypedAccessPath extends TUntypedAccessPath {
/** Gets a typed version of this untyped access path. */
AccessPath getATyped() {
this = TNilUntyped() and result = TNil(_)
or
exists(Content f | this = TConsNilUntyped(f) | result = TConsNil(f, _))
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
result = TConsCons(f1, f2, len)
)
}
string toString() {
this = TNilUntyped() and
result = "<nil>"
or
exists(Content f | this = TConsNilUntyped(f) | result = "[" + f + "]")
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
if len = 2
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
)
}
}
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, UntypedAccessPath uap) {
exists(ReturnNodeExt ret, Configuration config, AccessPath ap |
ap = uap.getATyped() and
flow(TNormalNode(p), true, ap, config)
|
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
exists(ReturnNodeExt ret, Configuration config | flow(TNormalNode(p), true, ap, config) |
exists(Summary summary |
parameterFlowReturn(p, ret, _, _, _, summary, config) and
flow(ret, unbind(config))
@@ -2080,12 +2037,30 @@ private newtype TSummaryCtx =
*
* Summaries are only created for parameters that may flow through.
*/
private class SummaryCtx extends TSummaryCtx {
string toString() { result = "SummaryCtx" }
abstract private class SummaryCtx extends TSummaryCtx {
abstract string toString();
}
/** A summary context from which no flow summary can be generated. */
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { }
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
override string toString() { result = "<none>" }
}
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
p.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private newtype TPathNode =
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
@@ -2399,22 +2374,22 @@ private predicate pathOutOfCallable(PathNodeMid mid, Node out, CallContext cc) {
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, UntypedAccessPath ap
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp().getUntyped()
ap = mid.getAp()
)
}
pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, UntypedAccessPath ap, Configuration config
DataFlowCallable callable, int i, AccessPath ap, Configuration config
) {
exists(ParameterNode p |
flow(TNormalNode(p), _, ap.getATyped(), config) and
flow(TNormalNode(p), _, ap, config) and
p.isParameterOf(callable, i)
)
}
@@ -2422,7 +2397,7 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
UntypedAccessPath ap
AccessPath ap
) {
pathIntoArg(mid, i, outercc, call, ap) and
callable = resolveCall(call, outercc) and
@@ -2438,7 +2413,7 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, UntypedAccessPath ap |
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap) and
p.isParameterOf(callable, i) and
(
@@ -2457,7 +2432,7 @@ private predicate pathIntoCallable(
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
pragma[nomagic]
private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, TSummaryCtxSome sc, AccessPath ap, Configuration config
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, Configuration config
) {
exists(PathNodeMid mid, ReturnNodeExt ret |
mid.getNode() = ret and
@@ -2635,14 +2610,7 @@ private module FlowExploration {
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
TSummaryCtx2Nil() or
TSummaryCtx2ConsNil(Content f)
private TSummaryCtx2 getSummaryCtx2(PartialAccessPath ap) {
result = TSummaryCtx2Nil() and ap instanceof PartialAccessPathNil
or
exists(Content f | result = TSummaryCtx2ConsNil(f) and ap = TPartialCons(f, 1))
}
TSummaryCtx2Some(PartialAccessPath ap)
private newtype TPartialPathNode =
TPartialPathNodeMk(
@@ -2929,11 +2897,8 @@ private module FlowExploration {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc1 = TSummaryCtx1Param(p) and sc2 = getSummaryCtx2(ap)
or
sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and not exists(getSummaryCtx2(ap))
)
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
if recordDataFlowCallSite(call, callable)
then innercc = TSpecificCall(call)
@@ -2953,8 +2918,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
config = mid.getConfiguration() and
ap = mid.getAp() and
ap.len() in [0 .. 1]
ap = mid.getAp()
)
}

View File

@@ -1647,9 +1647,6 @@ abstract private class AccessPath extends TAccessPath {
* Holds if this access path has `head` at the front and may be followed by `tail`.
*/
abstract predicate pop(Content head, AccessPath tail);
/** Gets the untyped version of this access path. */
UntypedAccessPath getUntyped() { result.getATyped() = this }
}
private class AccessPathNil extends AccessPath, TNil {
@@ -2001,50 +1998,10 @@ private Configuration unbind(Configuration conf) { result >= conf and result <=
private predicate flow(Node n, Configuration config) { flow(TNormalNode(n), _, _, config) }
private newtype TUntypedAccessPath =
TNilUntyped() or
TConsNilUntyped(Content f) { exists(TConsNil(f, _)) } or
TConsConsUntyped(Content f1, Content f2, int len) { exists(TConsCons(f1, f2, len)) }
/**
* An untyped access path.
*
* Untyped access paths are only used when reconstructing flow summaries,
* where the extra type information is redundant.
*/
private class UntypedAccessPath extends TUntypedAccessPath {
/** Gets a typed version of this untyped access path. */
AccessPath getATyped() {
this = TNilUntyped() and result = TNil(_)
or
exists(Content f | this = TConsNilUntyped(f) | result = TConsNil(f, _))
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
result = TConsCons(f1, f2, len)
)
}
string toString() {
this = TNilUntyped() and
result = "<nil>"
or
exists(Content f | this = TConsNilUntyped(f) | result = "[" + f + "]")
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
if len = 2
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
)
}
}
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, UntypedAccessPath uap) {
exists(ReturnNodeExt ret, Configuration config, AccessPath ap |
ap = uap.getATyped() and
flow(TNormalNode(p), true, ap, config)
|
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
exists(ReturnNodeExt ret, Configuration config | flow(TNormalNode(p), true, ap, config) |
exists(Summary summary |
parameterFlowReturn(p, ret, _, _, _, summary, config) and
flow(ret, unbind(config))
@@ -2080,12 +2037,30 @@ private newtype TSummaryCtx =
*
* Summaries are only created for parameters that may flow through.
*/
private class SummaryCtx extends TSummaryCtx {
string toString() { result = "SummaryCtx" }
abstract private class SummaryCtx extends TSummaryCtx {
abstract string toString();
}
/** A summary context from which no flow summary can be generated. */
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { }
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
override string toString() { result = "<none>" }
}
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
p.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private newtype TPathNode =
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
@@ -2399,22 +2374,22 @@ private predicate pathOutOfCallable(PathNodeMid mid, Node out, CallContext cc) {
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, UntypedAccessPath ap
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp().getUntyped()
ap = mid.getAp()
)
}
pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, UntypedAccessPath ap, Configuration config
DataFlowCallable callable, int i, AccessPath ap, Configuration config
) {
exists(ParameterNode p |
flow(TNormalNode(p), _, ap.getATyped(), config) and
flow(TNormalNode(p), _, ap, config) and
p.isParameterOf(callable, i)
)
}
@@ -2422,7 +2397,7 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
UntypedAccessPath ap
AccessPath ap
) {
pathIntoArg(mid, i, outercc, call, ap) and
callable = resolveCall(call, outercc) and
@@ -2438,7 +2413,7 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, UntypedAccessPath ap |
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap) and
p.isParameterOf(callable, i) and
(
@@ -2457,7 +2432,7 @@ private predicate pathIntoCallable(
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
pragma[nomagic]
private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, TSummaryCtxSome sc, AccessPath ap, Configuration config
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, Configuration config
) {
exists(PathNodeMid mid, ReturnNodeExt ret |
mid.getNode() = ret and
@@ -2635,14 +2610,7 @@ private module FlowExploration {
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
TSummaryCtx2Nil() or
TSummaryCtx2ConsNil(Content f)
private TSummaryCtx2 getSummaryCtx2(PartialAccessPath ap) {
result = TSummaryCtx2Nil() and ap instanceof PartialAccessPathNil
or
exists(Content f | result = TSummaryCtx2ConsNil(f) and ap = TPartialCons(f, 1))
}
TSummaryCtx2Some(PartialAccessPath ap)
private newtype TPartialPathNode =
TPartialPathNodeMk(
@@ -2929,11 +2897,8 @@ private module FlowExploration {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc1 = TSummaryCtx1Param(p) and sc2 = getSummaryCtx2(ap)
or
sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and not exists(getSummaryCtx2(ap))
)
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
if recordDataFlowCallSite(call, callable)
then innercc = TSpecificCall(call)
@@ -2953,8 +2918,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
config = mid.getConfiguration() and
ap = mid.getAp() and
ap.len() in [0 .. 1]
ap = mid.getAp()
)
}

View File

@@ -1647,9 +1647,6 @@ abstract private class AccessPath extends TAccessPath {
* Holds if this access path has `head` at the front and may be followed by `tail`.
*/
abstract predicate pop(Content head, AccessPath tail);
/** Gets the untyped version of this access path. */
UntypedAccessPath getUntyped() { result.getATyped() = this }
}
private class AccessPathNil extends AccessPath, TNil {
@@ -2001,50 +1998,10 @@ private Configuration unbind(Configuration conf) { result >= conf and result <=
private predicate flow(Node n, Configuration config) { flow(TNormalNode(n), _, _, config) }
private newtype TUntypedAccessPath =
TNilUntyped() or
TConsNilUntyped(Content f) { exists(TConsNil(f, _)) } or
TConsConsUntyped(Content f1, Content f2, int len) { exists(TConsCons(f1, f2, len)) }
/**
* An untyped access path.
*
* Untyped access paths are only used when reconstructing flow summaries,
* where the extra type information is redundant.
*/
private class UntypedAccessPath extends TUntypedAccessPath {
/** Gets a typed version of this untyped access path. */
AccessPath getATyped() {
this = TNilUntyped() and result = TNil(_)
or
exists(Content f | this = TConsNilUntyped(f) | result = TConsNil(f, _))
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
result = TConsCons(f1, f2, len)
)
}
string toString() {
this = TNilUntyped() and
result = "<nil>"
or
exists(Content f | this = TConsNilUntyped(f) | result = "[" + f + "]")
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
if len = 2
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
)
}
}
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, UntypedAccessPath uap) {
exists(ReturnNodeExt ret, Configuration config, AccessPath ap |
ap = uap.getATyped() and
flow(TNormalNode(p), true, ap, config)
|
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
exists(ReturnNodeExt ret, Configuration config | flow(TNormalNode(p), true, ap, config) |
exists(Summary summary |
parameterFlowReturn(p, ret, _, _, _, summary, config) and
flow(ret, unbind(config))
@@ -2080,12 +2037,30 @@ private newtype TSummaryCtx =
*
* Summaries are only created for parameters that may flow through.
*/
private class SummaryCtx extends TSummaryCtx {
string toString() { result = "SummaryCtx" }
abstract private class SummaryCtx extends TSummaryCtx {
abstract string toString();
}
/** A summary context from which no flow summary can be generated. */
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { }
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
override string toString() { result = "<none>" }
}
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
p.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private newtype TPathNode =
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
@@ -2399,22 +2374,22 @@ private predicate pathOutOfCallable(PathNodeMid mid, Node out, CallContext cc) {
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, UntypedAccessPath ap
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp().getUntyped()
ap = mid.getAp()
)
}
pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, UntypedAccessPath ap, Configuration config
DataFlowCallable callable, int i, AccessPath ap, Configuration config
) {
exists(ParameterNode p |
flow(TNormalNode(p), _, ap.getATyped(), config) and
flow(TNormalNode(p), _, ap, config) and
p.isParameterOf(callable, i)
)
}
@@ -2422,7 +2397,7 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
UntypedAccessPath ap
AccessPath ap
) {
pathIntoArg(mid, i, outercc, call, ap) and
callable = resolveCall(call, outercc) and
@@ -2438,7 +2413,7 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, UntypedAccessPath ap |
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap) and
p.isParameterOf(callable, i) and
(
@@ -2457,7 +2432,7 @@ private predicate pathIntoCallable(
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
pragma[nomagic]
private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, TSummaryCtxSome sc, AccessPath ap, Configuration config
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, Configuration config
) {
exists(PathNodeMid mid, ReturnNodeExt ret |
mid.getNode() = ret and
@@ -2635,14 +2610,7 @@ private module FlowExploration {
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
TSummaryCtx2Nil() or
TSummaryCtx2ConsNil(Content f)
private TSummaryCtx2 getSummaryCtx2(PartialAccessPath ap) {
result = TSummaryCtx2Nil() and ap instanceof PartialAccessPathNil
or
exists(Content f | result = TSummaryCtx2ConsNil(f) and ap = TPartialCons(f, 1))
}
TSummaryCtx2Some(PartialAccessPath ap)
private newtype TPartialPathNode =
TPartialPathNodeMk(
@@ -2929,11 +2897,8 @@ private module FlowExploration {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc1 = TSummaryCtx1Param(p) and sc2 = getSummaryCtx2(ap)
or
sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and not exists(getSummaryCtx2(ap))
)
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
if recordDataFlowCallSite(call, callable)
then innercc = TSpecificCall(call)
@@ -2953,8 +2918,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
config = mid.getConfiguration() and
ap = mid.getAp() and
ap.len() in [0 .. 1]
ap = mid.getAp()
)
}

View File

@@ -1647,9 +1647,6 @@ abstract private class AccessPath extends TAccessPath {
* Holds if this access path has `head` at the front and may be followed by `tail`.
*/
abstract predicate pop(Content head, AccessPath tail);
/** Gets the untyped version of this access path. */
UntypedAccessPath getUntyped() { result.getATyped() = this }
}
private class AccessPathNil extends AccessPath, TNil {
@@ -2001,50 +1998,10 @@ private Configuration unbind(Configuration conf) { result >= conf and result <=
private predicate flow(Node n, Configuration config) { flow(TNormalNode(n), _, _, config) }
private newtype TUntypedAccessPath =
TNilUntyped() or
TConsNilUntyped(Content f) { exists(TConsNil(f, _)) } or
TConsConsUntyped(Content f1, Content f2, int len) { exists(TConsCons(f1, f2, len)) }
/**
* An untyped access path.
*
* Untyped access paths are only used when reconstructing flow summaries,
* where the extra type information is redundant.
*/
private class UntypedAccessPath extends TUntypedAccessPath {
/** Gets a typed version of this untyped access path. */
AccessPath getATyped() {
this = TNilUntyped() and result = TNil(_)
or
exists(Content f | this = TConsNilUntyped(f) | result = TConsNil(f, _))
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
result = TConsCons(f1, f2, len)
)
}
string toString() {
this = TNilUntyped() and
result = "<nil>"
or
exists(Content f | this = TConsNilUntyped(f) | result = "[" + f + "]")
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
if len = 2
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
)
}
}
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, UntypedAccessPath uap) {
exists(ReturnNodeExt ret, Configuration config, AccessPath ap |
ap = uap.getATyped() and
flow(TNormalNode(p), true, ap, config)
|
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
exists(ReturnNodeExt ret, Configuration config | flow(TNormalNode(p), true, ap, config) |
exists(Summary summary |
parameterFlowReturn(p, ret, _, _, _, summary, config) and
flow(ret, unbind(config))
@@ -2080,12 +2037,30 @@ private newtype TSummaryCtx =
*
* Summaries are only created for parameters that may flow through.
*/
private class SummaryCtx extends TSummaryCtx {
string toString() { result = "SummaryCtx" }
abstract private class SummaryCtx extends TSummaryCtx {
abstract string toString();
}
/** A summary context from which no flow summary can be generated. */
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { }
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
override string toString() { result = "<none>" }
}
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
p.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private newtype TPathNode =
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
@@ -2399,22 +2374,22 @@ private predicate pathOutOfCallable(PathNodeMid mid, Node out, CallContext cc) {
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, UntypedAccessPath ap
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp().getUntyped()
ap = mid.getAp()
)
}
pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, UntypedAccessPath ap, Configuration config
DataFlowCallable callable, int i, AccessPath ap, Configuration config
) {
exists(ParameterNode p |
flow(TNormalNode(p), _, ap.getATyped(), config) and
flow(TNormalNode(p), _, ap, config) and
p.isParameterOf(callable, i)
)
}
@@ -2422,7 +2397,7 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
UntypedAccessPath ap
AccessPath ap
) {
pathIntoArg(mid, i, outercc, call, ap) and
callable = resolveCall(call, outercc) and
@@ -2438,7 +2413,7 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, UntypedAccessPath ap |
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap) and
p.isParameterOf(callable, i) and
(
@@ -2457,7 +2432,7 @@ private predicate pathIntoCallable(
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
pragma[nomagic]
private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, TSummaryCtxSome sc, AccessPath ap, Configuration config
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, Configuration config
) {
exists(PathNodeMid mid, ReturnNodeExt ret |
mid.getNode() = ret and
@@ -2635,14 +2610,7 @@ private module FlowExploration {
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
TSummaryCtx2Nil() or
TSummaryCtx2ConsNil(Content f)
private TSummaryCtx2 getSummaryCtx2(PartialAccessPath ap) {
result = TSummaryCtx2Nil() and ap instanceof PartialAccessPathNil
or
exists(Content f | result = TSummaryCtx2ConsNil(f) and ap = TPartialCons(f, 1))
}
TSummaryCtx2Some(PartialAccessPath ap)
private newtype TPartialPathNode =
TPartialPathNodeMk(
@@ -2929,11 +2897,8 @@ private module FlowExploration {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc1 = TSummaryCtx1Param(p) and sc2 = getSummaryCtx2(ap)
or
sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and not exists(getSummaryCtx2(ap))
)
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
if recordDataFlowCallSite(call, callable)
then innercc = TSpecificCall(call)
@@ -2953,8 +2918,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
config = mid.getConfiguration() and
ap = mid.getAp() and
ap.len() in [0 .. 1]
ap = mid.getAp()
)
}

View File

@@ -1647,9 +1647,6 @@ abstract private class AccessPath extends TAccessPath {
* Holds if this access path has `head` at the front and may be followed by `tail`.
*/
abstract predicate pop(Content head, AccessPath tail);
/** Gets the untyped version of this access path. */
UntypedAccessPath getUntyped() { result.getATyped() = this }
}
private class AccessPathNil extends AccessPath, TNil {
@@ -2001,50 +1998,10 @@ private Configuration unbind(Configuration conf) { result >= conf and result <=
private predicate flow(Node n, Configuration config) { flow(TNormalNode(n), _, _, config) }
private newtype TUntypedAccessPath =
TNilUntyped() or
TConsNilUntyped(Content f) { exists(TConsNil(f, _)) } or
TConsConsUntyped(Content f1, Content f2, int len) { exists(TConsCons(f1, f2, len)) }
/**
* An untyped access path.
*
* Untyped access paths are only used when reconstructing flow summaries,
* where the extra type information is redundant.
*/
private class UntypedAccessPath extends TUntypedAccessPath {
/** Gets a typed version of this untyped access path. */
AccessPath getATyped() {
this = TNilUntyped() and result = TNil(_)
or
exists(Content f | this = TConsNilUntyped(f) | result = TConsNil(f, _))
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
result = TConsCons(f1, f2, len)
)
}
string toString() {
this = TNilUntyped() and
result = "<nil>"
or
exists(Content f | this = TConsNilUntyped(f) | result = "[" + f + "]")
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
if len = 2
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
)
}
}
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, UntypedAccessPath uap) {
exists(ReturnNodeExt ret, Configuration config, AccessPath ap |
ap = uap.getATyped() and
flow(TNormalNode(p), true, ap, config)
|
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
exists(ReturnNodeExt ret, Configuration config | flow(TNormalNode(p), true, ap, config) |
exists(Summary summary |
parameterFlowReturn(p, ret, _, _, _, summary, config) and
flow(ret, unbind(config))
@@ -2080,12 +2037,30 @@ private newtype TSummaryCtx =
*
* Summaries are only created for parameters that may flow through.
*/
private class SummaryCtx extends TSummaryCtx {
string toString() { result = "SummaryCtx" }
abstract private class SummaryCtx extends TSummaryCtx {
abstract string toString();
}
/** A summary context from which no flow summary can be generated. */
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { }
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
override string toString() { result = "<none>" }
}
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
p.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private newtype TPathNode =
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
@@ -2399,22 +2374,22 @@ private predicate pathOutOfCallable(PathNodeMid mid, Node out, CallContext cc) {
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, UntypedAccessPath ap
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp().getUntyped()
ap = mid.getAp()
)
}
pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, UntypedAccessPath ap, Configuration config
DataFlowCallable callable, int i, AccessPath ap, Configuration config
) {
exists(ParameterNode p |
flow(TNormalNode(p), _, ap.getATyped(), config) and
flow(TNormalNode(p), _, ap, config) and
p.isParameterOf(callable, i)
)
}
@@ -2422,7 +2397,7 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
UntypedAccessPath ap
AccessPath ap
) {
pathIntoArg(mid, i, outercc, call, ap) and
callable = resolveCall(call, outercc) and
@@ -2438,7 +2413,7 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, UntypedAccessPath ap |
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap) and
p.isParameterOf(callable, i) and
(
@@ -2457,7 +2432,7 @@ private predicate pathIntoCallable(
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
pragma[nomagic]
private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, TSummaryCtxSome sc, AccessPath ap, Configuration config
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, Configuration config
) {
exists(PathNodeMid mid, ReturnNodeExt ret |
mid.getNode() = ret and
@@ -2635,14 +2610,7 @@ private module FlowExploration {
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
TSummaryCtx2Nil() or
TSummaryCtx2ConsNil(Content f)
private TSummaryCtx2 getSummaryCtx2(PartialAccessPath ap) {
result = TSummaryCtx2Nil() and ap instanceof PartialAccessPathNil
or
exists(Content f | result = TSummaryCtx2ConsNil(f) and ap = TPartialCons(f, 1))
}
TSummaryCtx2Some(PartialAccessPath ap)
private newtype TPartialPathNode =
TPartialPathNodeMk(
@@ -2929,11 +2897,8 @@ private module FlowExploration {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc1 = TSummaryCtx1Param(p) and sc2 = getSummaryCtx2(ap)
or
sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and not exists(getSummaryCtx2(ap))
)
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
if recordDataFlowCallSite(call, callable)
then innercc = TSpecificCall(call)
@@ -2953,8 +2918,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
config = mid.getConfiguration() and
ap = mid.getAp() and
ap.len() in [0 .. 1]
ap = mid.getAp()
)
}

View File

@@ -1647,9 +1647,6 @@ abstract private class AccessPath extends TAccessPath {
* Holds if this access path has `head` at the front and may be followed by `tail`.
*/
abstract predicate pop(Content head, AccessPath tail);
/** Gets the untyped version of this access path. */
UntypedAccessPath getUntyped() { result.getATyped() = this }
}
private class AccessPathNil extends AccessPath, TNil {
@@ -2001,50 +1998,10 @@ private Configuration unbind(Configuration conf) { result >= conf and result <=
private predicate flow(Node n, Configuration config) { flow(TNormalNode(n), _, _, config) }
private newtype TUntypedAccessPath =
TNilUntyped() or
TConsNilUntyped(Content f) { exists(TConsNil(f, _)) } or
TConsConsUntyped(Content f1, Content f2, int len) { exists(TConsCons(f1, f2, len)) }
/**
* An untyped access path.
*
* Untyped access paths are only used when reconstructing flow summaries,
* where the extra type information is redundant.
*/
private class UntypedAccessPath extends TUntypedAccessPath {
/** Gets a typed version of this untyped access path. */
AccessPath getATyped() {
this = TNilUntyped() and result = TNil(_)
or
exists(Content f | this = TConsNilUntyped(f) | result = TConsNil(f, _))
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
result = TConsCons(f1, f2, len)
)
}
string toString() {
this = TNilUntyped() and
result = "<nil>"
or
exists(Content f | this = TConsNilUntyped(f) | result = "[" + f + "]")
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
if len = 2
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
)
}
}
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, UntypedAccessPath uap) {
exists(ReturnNodeExt ret, Configuration config, AccessPath ap |
ap = uap.getATyped() and
flow(TNormalNode(p), true, ap, config)
|
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
exists(ReturnNodeExt ret, Configuration config | flow(TNormalNode(p), true, ap, config) |
exists(Summary summary |
parameterFlowReturn(p, ret, _, _, _, summary, config) and
flow(ret, unbind(config))
@@ -2080,12 +2037,30 @@ private newtype TSummaryCtx =
*
* Summaries are only created for parameters that may flow through.
*/
private class SummaryCtx extends TSummaryCtx {
string toString() { result = "SummaryCtx" }
abstract private class SummaryCtx extends TSummaryCtx {
abstract string toString();
}
/** A summary context from which no flow summary can be generated. */
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { }
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
override string toString() { result = "<none>" }
}
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
p.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private newtype TPathNode =
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
@@ -2399,22 +2374,22 @@ private predicate pathOutOfCallable(PathNodeMid mid, Node out, CallContext cc) {
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, UntypedAccessPath ap
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp().getUntyped()
ap = mid.getAp()
)
}
pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, UntypedAccessPath ap, Configuration config
DataFlowCallable callable, int i, AccessPath ap, Configuration config
) {
exists(ParameterNode p |
flow(TNormalNode(p), _, ap.getATyped(), config) and
flow(TNormalNode(p), _, ap, config) and
p.isParameterOf(callable, i)
)
}
@@ -2422,7 +2397,7 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
UntypedAccessPath ap
AccessPath ap
) {
pathIntoArg(mid, i, outercc, call, ap) and
callable = resolveCall(call, outercc) and
@@ -2438,7 +2413,7 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, UntypedAccessPath ap |
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap) and
p.isParameterOf(callable, i) and
(
@@ -2457,7 +2432,7 @@ private predicate pathIntoCallable(
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
pragma[nomagic]
private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, TSummaryCtxSome sc, AccessPath ap, Configuration config
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, Configuration config
) {
exists(PathNodeMid mid, ReturnNodeExt ret |
mid.getNode() = ret and
@@ -2635,14 +2610,7 @@ private module FlowExploration {
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
TSummaryCtx2Nil() or
TSummaryCtx2ConsNil(Content f)
private TSummaryCtx2 getSummaryCtx2(PartialAccessPath ap) {
result = TSummaryCtx2Nil() and ap instanceof PartialAccessPathNil
or
exists(Content f | result = TSummaryCtx2ConsNil(f) and ap = TPartialCons(f, 1))
}
TSummaryCtx2Some(PartialAccessPath ap)
private newtype TPartialPathNode =
TPartialPathNodeMk(
@@ -2929,11 +2897,8 @@ private module FlowExploration {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc1 = TSummaryCtx1Param(p) and sc2 = getSummaryCtx2(ap)
or
sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and not exists(getSummaryCtx2(ap))
)
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
if recordDataFlowCallSite(call, callable)
then innercc = TSpecificCall(call)
@@ -2953,8 +2918,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
config = mid.getConfiguration() and
ap = mid.getAp() and
ap.len() in [0 .. 1]
ap = mid.getAp()
)
}

View File

@@ -1647,9 +1647,6 @@ abstract private class AccessPath extends TAccessPath {
* Holds if this access path has `head` at the front and may be followed by `tail`.
*/
abstract predicate pop(Content head, AccessPath tail);
/** Gets the untyped version of this access path. */
UntypedAccessPath getUntyped() { result.getATyped() = this }
}
private class AccessPathNil extends AccessPath, TNil {
@@ -2001,50 +1998,10 @@ private Configuration unbind(Configuration conf) { result >= conf and result <=
private predicate flow(Node n, Configuration config) { flow(TNormalNode(n), _, _, config) }
private newtype TUntypedAccessPath =
TNilUntyped() or
TConsNilUntyped(Content f) { exists(TConsNil(f, _)) } or
TConsConsUntyped(Content f1, Content f2, int len) { exists(TConsCons(f1, f2, len)) }
/**
* An untyped access path.
*
* Untyped access paths are only used when reconstructing flow summaries,
* where the extra type information is redundant.
*/
private class UntypedAccessPath extends TUntypedAccessPath {
/** Gets a typed version of this untyped access path. */
AccessPath getATyped() {
this = TNilUntyped() and result = TNil(_)
or
exists(Content f | this = TConsNilUntyped(f) | result = TConsNil(f, _))
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
result = TConsCons(f1, f2, len)
)
}
string toString() {
this = TNilUntyped() and
result = "<nil>"
or
exists(Content f | this = TConsNilUntyped(f) | result = "[" + f + "]")
or
exists(Content f1, Content f2, int len | this = TConsConsUntyped(f1, f2, len) |
if len = 2
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
)
}
}
private newtype TSummaryCtx =
TSummaryCtxNone() or
TSummaryCtxSome(ParameterNode p, UntypedAccessPath uap) {
exists(ReturnNodeExt ret, Configuration config, AccessPath ap |
ap = uap.getATyped() and
flow(TNormalNode(p), true, ap, config)
|
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
exists(ReturnNodeExt ret, Configuration config | flow(TNormalNode(p), true, ap, config) |
exists(Summary summary |
parameterFlowReturn(p, ret, _, _, _, summary, config) and
flow(ret, unbind(config))
@@ -2080,12 +2037,30 @@ private newtype TSummaryCtx =
*
* Summaries are only created for parameters that may flow through.
*/
private class SummaryCtx extends TSummaryCtx {
string toString() { result = "SummaryCtx" }
abstract private class SummaryCtx extends TSummaryCtx {
abstract string toString();
}
/** A summary context from which no flow summary can be generated. */
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { }
private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
override string toString() { result = "<none>" }
}
/** A summary context from which a flow summary can be generated. */
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
private ParameterNode p;
private AccessPath ap;
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
p.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private newtype TPathNode =
TPathNodeMid(Node node, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config) {
@@ -2399,22 +2374,22 @@ private predicate pathOutOfCallable(PathNodeMid mid, Node out, CallContext cc) {
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, UntypedAccessPath ap
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap
) {
exists(ArgumentNode arg |
arg = mid.getNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp().getUntyped()
ap = mid.getAp()
)
}
pragma[noinline]
private predicate parameterCand(
DataFlowCallable callable, int i, UntypedAccessPath ap, Configuration config
DataFlowCallable callable, int i, AccessPath ap, Configuration config
) {
exists(ParameterNode p |
flow(TNormalNode(p), _, ap.getATyped(), config) and
flow(TNormalNode(p), _, ap, config) and
p.isParameterOf(callable, i)
)
}
@@ -2422,7 +2397,7 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
UntypedAccessPath ap
AccessPath ap
) {
pathIntoArg(mid, i, outercc, call, ap) and
callable = resolveCall(call, outercc) and
@@ -2438,7 +2413,7 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call
) {
exists(int i, DataFlowCallable callable, UntypedAccessPath ap |
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap) and
p.isParameterOf(callable, i) and
(
@@ -2457,7 +2432,7 @@ private predicate pathIntoCallable(
/** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */
pragma[nomagic]
private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, TSummaryCtxSome sc, AccessPath ap, Configuration config
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, Configuration config
) {
exists(PathNodeMid mid, ReturnNodeExt ret |
mid.getNode() = ret and
@@ -2635,14 +2610,7 @@ private module FlowExploration {
private newtype TSummaryCtx2 =
TSummaryCtx2None() or
TSummaryCtx2Nil() or
TSummaryCtx2ConsNil(Content f)
private TSummaryCtx2 getSummaryCtx2(PartialAccessPath ap) {
result = TSummaryCtx2Nil() and ap instanceof PartialAccessPathNil
or
exists(Content f | result = TSummaryCtx2ConsNil(f) and ap = TPartialCons(f, 1))
}
TSummaryCtx2Some(PartialAccessPath ap)
private newtype TPartialPathNode =
TPartialPathNodeMk(
@@ -2929,11 +2897,8 @@ private module FlowExploration {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc1 = TSummaryCtx1Param(p) and sc2 = getSummaryCtx2(ap)
or
sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and not exists(getSummaryCtx2(ap))
)
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
if recordDataFlowCallSite(call, callable)
then innercc = TSpecificCall(call)
@@ -2953,8 +2918,7 @@ private module FlowExploration {
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
config = mid.getConfiguration() and
ap = mid.getAp() and
ap.len() in [0 .. 1]
ap = mid.getAp()
)
}