зеркало из https://github.com/github/codeql.git
Address review comments
This commit is contained in:
Родитель
ec5d8ab2db
Коммит
dd138b0429
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -802,7 +802,7 @@ private module Cached {
|
|||
}
|
||||
|
||||
cached
|
||||
predicate allowFlowThroughParameterCached(Node ret) { allowFlowThroughParameter(ret) }
|
||||
predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
|
||||
|
||||
cached
|
||||
newtype TCallContext =
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -288,5 +288,8 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { no
|
|||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
|
||||
|
||||
/** Holds if flow is allowed to pass into `p` and back out again. */
|
||||
predicate allowFlowThroughParameter(ParameterNode p) { none() }
|
||||
/**
|
||||
* Holds if flow is allowed to pass from parameter `p`, to a return
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate allowParameterReturnInSelf(ParameterNode p) { none() }
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -802,7 +802,7 @@ private module Cached {
|
|||
}
|
||||
|
||||
cached
|
||||
predicate allowFlowThroughParameterCached(Node ret) { allowFlowThroughParameter(ret) }
|
||||
predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
|
||||
|
||||
cached
|
||||
newtype TCallContext =
|
||||
|
|
|
@ -508,5 +508,8 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { no
|
|||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
|
||||
|
||||
/** Holds if flow is allowed to pass into `p` and back out again. */
|
||||
predicate allowFlowThroughParameter(ParameterNode p) { none() }
|
||||
/**
|
||||
* Holds if flow is allowed to pass from parameter `p`, to a return
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate allowParameterReturnInSelf(ParameterNode p) { none() }
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -802,7 +802,7 @@ private module Cached {
|
|||
}
|
||||
|
||||
cached
|
||||
predicate allowFlowThroughParameterCached(Node ret) { allowFlowThroughParameter(ret) }
|
||||
predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
|
||||
|
||||
cached
|
||||
newtype TCallContext =
|
||||
|
|
|
@ -2015,9 +2015,9 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
|
|||
}
|
||||
|
||||
/**
|
||||
* Holds if flow is allowed to pass from a parameter `p`, to return
|
||||
* node `ret`, and back out to `p`.
|
||||
* Holds if flow is allowed to pass from parameter `p`, to a return
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate allowFlowThroughParameter(ReturnNodeExt ret) {
|
||||
FlowSummaryImpl::Private::summaryAllowFlowThroughParameter(ret)
|
||||
predicate allowParameterReturnInSelf(ParameterNode p) {
|
||||
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p)
|
||||
}
|
||||
|
|
|
@ -504,11 +504,14 @@ module Private {
|
|||
}
|
||||
|
||||
/**
|
||||
* Holds if flow is allowed to pass from a parameter `p`, to return
|
||||
* node `ret`, and back out to `p`.
|
||||
* Holds if flow is allowed to pass from parameter `p`, to a return
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowFlowThroughParameter(ReturnNodeExt ret) {
|
||||
ret = summaryNode(_, TSummaryNodeClearsContentState(_, true))
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, int i |
|
||||
c.clearsContent(i, _) and
|
||||
p.isParameterOf(c, i)
|
||||
)
|
||||
}
|
||||
|
||||
/** Provides a compilation of flow summaries to atomic data-flow steps. */
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -802,7 +802,7 @@ private module Cached {
|
|||
}
|
||||
|
||||
cached
|
||||
predicate allowFlowThroughParameterCached(Node ret) { allowFlowThroughParameter(ret) }
|
||||
predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
|
||||
|
||||
cached
|
||||
newtype TCallContext =
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -367,9 +367,9 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
|||
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
|
||||
|
||||
/**
|
||||
* Holds if flow is allowed to pass from a parameter `p`, to return
|
||||
* node `ret`, and back out to `p`.
|
||||
* Holds if flow is allowed to pass from parameter `p`, to a return
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate allowFlowThroughParameter(ReturnNodeExt ret) {
|
||||
FlowSummaryImpl::Private::summaryAllowFlowThroughParameter(ret)
|
||||
predicate allowParameterReturnInSelf(ParameterNode p) {
|
||||
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p)
|
||||
}
|
||||
|
|
|
@ -504,11 +504,14 @@ module Private {
|
|||
}
|
||||
|
||||
/**
|
||||
* Holds if flow is allowed to pass from a parameter `p`, to return
|
||||
* node `ret`, and back out to `p`.
|
||||
* Holds if flow is allowed to pass from parameter `p`, to a return
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowFlowThroughParameter(ReturnNodeExt ret) {
|
||||
ret = summaryNode(_, TSummaryNodeClearsContentState(_, true))
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, int i |
|
||||
c.clearsContent(i, _) and
|
||||
p.isParameterOf(c, i)
|
||||
)
|
||||
}
|
||||
|
||||
/** Provides a compilation of flow summaries to atomic data-flow steps. */
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
|
|||
}
|
||||
|
||||
int getPosition() { this.isParameterOf(_, result) }
|
||||
|
||||
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private class RetNodeEx extends NodeEx {
|
||||
|
@ -252,8 +254,6 @@ private class RetNodeEx extends NodeEx {
|
|||
ReturnPosition getReturnPosition() { result = getReturnPosition(this.asNode()) }
|
||||
|
||||
ReturnKindExt getKind() { result = this.asNode().(ReturnNodeExt).getKind() }
|
||||
|
||||
predicate allowFlowThroughParameter() { allowFlowThroughParameterCached(this.asNode()) }
|
||||
}
|
||||
|
||||
private predicate inBarrier(NodeEx node, Configuration config) {
|
||||
|
@ -727,16 +727,12 @@ private module Stage1 {
|
|||
/** Holds if flow may return from `callable`. */
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowCallableNodeCand(
|
||||
DataFlowCallable callable, ReturnKindExt kind, boolean allowFlowThroughParameter,
|
||||
Configuration config
|
||||
DataFlowCallable callable, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret |
|
||||
throughFlowNodeCand(ret, config) and
|
||||
callable = ret.getEnclosingCallable() and
|
||||
kind = ret.getKind() and
|
||||
if ret.allowFlowThroughParameter()
|
||||
then allowFlowThroughParameter = true
|
||||
else allowFlowThroughParameter = false
|
||||
kind = ret.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -745,16 +741,17 @@ private module Stage1 {
|
|||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind, boolean allowFlowThroughParameter |
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, allowFlowThroughParameter, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
p.getEnclosingCallable() = c and
|
||||
exists(ap) and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then allowFlowThroughParameter = true
|
||||
else any()
|
||||
) and
|
||||
exists(ap)
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1403,10 +1400,11 @@ private module Stage2 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2095,10 +2093,11 @@ private module Stage3 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2858,10 +2857,11 @@ private module Stage4 {
|
|||
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
|
||||
kind = ret.getKind() and
|
||||
p.getPosition() = pos and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
p.allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -2935,7 +2935,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
|||
|
||||
int getParameterPos() { p.isParameterOf(_, result) }
|
||||
|
||||
ParameterNode getParameterNode() { result = p.asNode() }
|
||||
ParamNodeEx getParamNode() { result = p }
|
||||
|
||||
override string toString() { result = p + ": " + ap }
|
||||
|
||||
|
@ -3637,10 +3637,11 @@ private predicate paramFlowsThrough(
|
|||
ap = mid.getAp() and
|
||||
apa = ap.getApprox() and
|
||||
pos = sc.getParameterPos() and
|
||||
// we don't expect a parameter to return stored in itself, unless explicitly allowed
|
||||
(
|
||||
if kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
then ret.allowFlowThroughParameter()
|
||||
else any()
|
||||
not kind.(ParamUpdateReturnKind).getPosition() = pos
|
||||
or
|
||||
sc.getParamNode().allowParameterReturnInSelf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -802,7 +802,7 @@ private module Cached {
|
|||
}
|
||||
|
||||
cached
|
||||
predicate allowFlowThroughParameterCached(Node ret) { allowFlowThroughParameter(ret) }
|
||||
predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
|
||||
|
||||
cached
|
||||
newtype TCallContext =
|
||||
|
|
|
@ -1665,5 +1665,8 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { no
|
|||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
|
||||
|
||||
/** Holds if flow is allowed to pass into `p` and back out again. */
|
||||
predicate allowFlowThroughParameter(ParameterNode p) { none() }
|
||||
/**
|
||||
* Holds if flow is allowed to pass from parameter `p`, to a return
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate allowParameterReturnInSelf(ParameterNode p) { none() }
|
||||
|
|
Загрузка…
Ссылка в новой задаче