python: sync file

This commit is contained in:
yoff
2022-05-16 08:12:25 +00:00
committed by GitHub
parent 2822ed9594
commit 5794e64940

View File

@@ -26,6 +26,10 @@ module Public {
string toString() { string toString() {
exists(ContentSet c | this = TContentSummaryComponent(c) and result = c.toString()) exists(ContentSet c | this = TContentSummaryComponent(c) and result = c.toString())
or or
exists(ContentSet c | this = TWithoutContentSummaryComponent(c) and result = "without " + c)
or
exists(ContentSet c | this = TWithContentSummaryComponent(c) and result = "with " + c)
or
exists(ArgumentPosition pos | exists(ArgumentPosition pos |
this = TParameterSummaryComponent(pos) and result = "parameter " + pos this = TParameterSummaryComponent(pos) and result = "parameter " + pos
) )
@@ -43,6 +47,12 @@ module Public {
/** Gets a summary component for content `c`. */ /** Gets a summary component for content `c`. */
SummaryComponent content(ContentSet c) { result = TContentSummaryComponent(c) } SummaryComponent content(ContentSet c) { result = TContentSummaryComponent(c) }
/** Gets a summary component where data is not allowed to be stored in `c`. */
SummaryComponent withoutContent(ContentSet c) { result = TWithoutContentSummaryComponent(c) }
/** Gets a summary component where data must be stored in `c`. */
SummaryComponent withContent(ContentSet c) { result = TWithContentSummaryComponent(c) }
/** Gets a summary component for a parameter at position `pos`. */ /** Gets a summary component for a parameter at position `pos`. */
SummaryComponent parameter(ArgumentPosition pos) { result = TParameterSummaryComponent(pos) } SummaryComponent parameter(ArgumentPosition pos) { result = TParameterSummaryComponent(pos) }
@@ -216,6 +226,8 @@ module Public {
/** /**
* Holds if values stored inside `content` are cleared on objects passed as * Holds if values stored inside `content` are cleared on objects passed as
* arguments at position `pos` to this callable. * arguments at position `pos` to this callable.
*
* TODO: Remove once all languages support `WithoutContent` tokens.
*/ */
pragma[nomagic] pragma[nomagic]
predicate clearsContent(ParameterPosition pos, ContentSet content) { none() } predicate clearsContent(ParameterPosition pos, ContentSet content) { none() }
@@ -239,7 +251,9 @@ module Private {
TContentSummaryComponent(ContentSet c) or TContentSummaryComponent(ContentSet c) or
TParameterSummaryComponent(ArgumentPosition pos) or TParameterSummaryComponent(ArgumentPosition pos) or
TArgumentSummaryComponent(ParameterPosition pos) or TArgumentSummaryComponent(ParameterPosition pos) or
TReturnSummaryComponent(ReturnKind rk) TReturnSummaryComponent(ReturnKind rk) or
TWithoutContentSummaryComponent(ContentSet c) or
TWithContentSummaryComponent(ContentSet c)
private TParameterSummaryComponent thisParam() { private TParameterSummaryComponent thisParam() {
result = TParameterSummaryComponent(instanceParameterPosition()) result = TParameterSummaryComponent(instanceParameterPosition())
@@ -301,6 +315,23 @@ module Private {
SummaryComponentStack::singleton(TArgumentSummaryComponent(_))) and SummaryComponentStack::singleton(TArgumentSummaryComponent(_))) and
preservesValue = preservesValue1.booleanAnd(preservesValue2) preservesValue = preservesValue1.booleanAnd(preservesValue2)
) )
or
exists(ParameterPosition ppos, ContentSet cs |
c.clearsContent(ppos, cs) and
input = SummaryComponentStack::push(SummaryComponent::withoutContent(cs), output) and
output = SummaryComponentStack::argument(ppos) and
preservesValue = true
)
}
private class MkClearStack extends RequiredSummaryComponentStack {
override predicate required(SummaryComponent head, SummaryComponentStack tail) {
exists(SummarizedCallable sc, ParameterPosition ppos, ContentSet cs |
sc.clearsContent(ppos, cs) and
head = SummaryComponent::withoutContent(cs) and
tail = SummaryComponentStack::argument(ppos)
)
}
} }
/** /**
@@ -383,10 +414,7 @@ module Private {
private newtype TSummaryNodeState = private newtype TSummaryNodeState =
TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or
TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } or TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) }
TSummaryNodeClearsContentState(ParameterPosition pos, boolean post) {
any(SummarizedCallable sc).clearsContent(pos, _) and post in [false, true]
}
/** /**
* A state used to break up (complex) flow summaries into atomic flow steps. * A state used to break up (complex) flow summaries into atomic flow steps.
@@ -433,12 +461,6 @@ module Private {
this = TSummaryNodeOutputState(s) and this = TSummaryNodeOutputState(s) and
result = "to write: " + s result = "to write: " + s
) )
or
exists(ParameterPosition pos, boolean post, string postStr |
this = TSummaryNodeClearsContentState(pos, post) and
(if post = true then postStr = " (post)" else postStr = "") and
result = "clear: " + pos + postStr
)
} }
} }
@@ -462,11 +484,6 @@ module Private {
not parameterReadState(c, state, _) not parameterReadState(c, state, _)
or or
state.isOutputState(c, _) state.isOutputState(c, _)
or
exists(ParameterPosition pos |
c.clearsContent(pos, _) and
state = TSummaryNodeClearsContentState(pos, _)
)
} }
pragma[noinline] pragma[noinline]
@@ -502,8 +519,6 @@ module Private {
parameterReadState(c, _, pos) parameterReadState(c, _, pos)
or or
isParameterPostUpdate(_, c, pos) isParameterPostUpdate(_, c, pos)
or
c.clearsContent(pos, _)
} }
private predicate callbackOutput( private predicate callbackOutput(
@@ -511,7 +526,7 @@ module Private {
) { ) {
any(SummaryNodeState state).isInputState(c, s) and any(SummaryNodeState state).isInputState(c, s) and
s.head() = TReturnSummaryComponent(rk) and s.head() = TReturnSummaryComponent(rk) and
receiver = summaryNodeInputState(c, s.drop(1)) receiver = summaryNodeInputState(c, s.tail())
} }
private predicate callbackInput( private predicate callbackInput(
@@ -519,7 +534,7 @@ module Private {
) { ) {
any(SummaryNodeState state).isOutputState(c, s) and any(SummaryNodeState state).isOutputState(c, s) and
s.head() = TParameterSummaryComponent(pos) and s.head() = TParameterSummaryComponent(pos) and
receiver = summaryNodeInputState(c, s.drop(1)) receiver = summaryNodeInputState(c, s.tail())
} }
/** Holds if a call targeting `receiver` should be synthesized inside `c`. */ /** Holds if a call targeting `receiver` should be synthesized inside `c`. */
@@ -545,15 +560,21 @@ module Private {
exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() |
n = summaryNodeInputState(c, s) and n = summaryNodeInputState(c, s) and
( (
exists(ContentSet cont | result = getContentType(cont) |
head = TContentSummaryComponent(cont) or
head = TWithContentSummaryComponent(cont)
)
or
exists(ContentSet cont | exists(ContentSet cont |
head = TContentSummaryComponent(cont) and result = getContentType(cont) head = TWithoutContentSummaryComponent(cont) and
result = getNodeType(summaryNodeInputState(c, s.tail()))
) )
or or
exists(ReturnKind rk | exists(ReturnKind rk |
head = TReturnSummaryComponent(rk) and head = TReturnSummaryComponent(rk) and
result = result =
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.drop(1))), rk) s.tail())), rk)
) )
) )
or or
@@ -572,16 +593,10 @@ module Private {
exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) | exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) |
result = result =
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.drop(1))), pos) s.tail())), pos)
) )
) )
) )
or
exists(SummarizedCallable c, ParameterPosition pos, ParamNode p |
n = summaryNode(c, TSummaryNodeClearsContentState(pos, false)) and
p.isParameterOf(c, pos) and
result = getNodeType(p)
)
} }
/** Holds if summary node `out` contains output of kind `rk` from call `c`. */ /** Holds if summary node `out` contains output of kind `rk` from call `c`. */
@@ -607,9 +622,6 @@ module Private {
exists(SummarizedCallable c, ParameterPosition pos | exists(SummarizedCallable c, ParameterPosition pos |
isParameterPostUpdate(post, c, pos) and isParameterPostUpdate(post, c, pos) and
pre.(ParamNode).isParameterOf(c, pos) pre.(ParamNode).isParameterOf(c, pos)
or
pre = summaryNode(c, TSummaryNodeClearsContentState(pos, false)) and
post = summaryNode(c, TSummaryNodeClearsContentState(pos, true))
) )
or or
exists(SummarizedCallable callable, SummaryComponentStack s | exists(SummarizedCallable callable, SummaryComponentStack s |
@@ -633,8 +645,6 @@ module Private {
*/ */
predicate summaryAllowParameterReturnInSelf(ParamNode p) { predicate summaryAllowParameterReturnInSelf(ParamNode p) {
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(c, ppos) | exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(c, ppos) |
c.clearsContent(ppos, _)
or
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents | exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
summary(c, inputContents, outputContents, _) and summary(c, inputContents, outputContents, _) and
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and
@@ -663,9 +673,10 @@ module Private {
preservesValue = false and not summary(c, inputContents, outputContents, true) preservesValue = false and not summary(c, inputContents, outputContents, true)
) )
or or
exists(SummarizedCallable c, ParameterPosition pos | exists(SummarizedCallable c, SummaryComponentStack s |
pred.(ParamNode).isParameterOf(c, pos) and pred = summaryNodeInputState(c, s.tail()) and
succ = summaryNode(c, TSummaryNodeClearsContentState(pos, _)) and succ = summaryNodeInputState(c, s) and
s.head() = [SummaryComponent::withContent(_), SummaryComponent::withoutContent(_)] and
preservesValue = true preservesValue = true
) )
} }
@@ -676,7 +687,7 @@ module Private {
*/ */
predicate summaryReadStep(Node pred, ContentSet c, Node succ) { predicate summaryReadStep(Node pred, ContentSet c, Node succ) {
exists(SummarizedCallable sc, SummaryComponentStack s | exists(SummarizedCallable sc, SummaryComponentStack s |
pred = summaryNodeInputState(sc, s.drop(1)) and pred = summaryNodeInputState(sc, s.tail()) and
succ = summaryNodeInputState(sc, s) and succ = summaryNodeInputState(sc, s) and
SummaryComponent::content(c) = s.head() SummaryComponent::content(c) = s.head()
) )
@@ -689,7 +700,7 @@ module Private {
predicate summaryStoreStep(Node pred, ContentSet c, Node succ) { predicate summaryStoreStep(Node pred, ContentSet c, Node succ) {
exists(SummarizedCallable sc, SummaryComponentStack s | exists(SummarizedCallable sc, SummaryComponentStack s |
pred = summaryNodeOutputState(sc, s) and pred = summaryNodeOutputState(sc, s) and
succ = summaryNodeOutputState(sc, s.drop(1)) and succ = summaryNodeOutputState(sc, s.tail()) and
SummaryComponent::content(c) = s.head() SummaryComponent::content(c) = s.head()
) )
} }
@@ -714,9 +725,22 @@ module Private {
* node where field `b` is cleared). * node where field `b` is cleared).
*/ */
predicate summaryClearsContent(Node n, ContentSet c) { predicate summaryClearsContent(Node n, ContentSet c) {
exists(SummarizedCallable sc, ParameterPosition pos | exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
n = summaryNode(sc, TSummaryNodeClearsContentState(pos, true)) and n = summaryNode(sc, state) and
sc.clearsContent(pos, c) state.isInputState(sc, stack) and
stack.head() = SummaryComponent::withoutContent(c)
)
}
/**
* Holds if the value that is being tracked is expected to be stored inside
* content `c` at `n`.
*/
predicate summaryExpectsContent(Node n, ContentSet c) {
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
n = summaryNode(sc, state) and
state.isInputState(sc, stack) and
stack.head() = SummaryComponent::withContent(c)
) )
} }
@@ -728,22 +752,6 @@ module Private {
sc = viableCallable(call) sc = viableCallable(call)
} }
/**
* Holds if values stored inside content `c` are cleared inside a
* callable to which `arg` is an argument.
*
* In such cases, it is important to prevent use-use flow out of
* `arg` (see comment for `summaryClearsContent`).
*/
pragma[nomagic]
predicate summaryClearsContentArg(ArgNode arg, ContentSet c) {
exists(DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos |
argumentPositionMatch(call, arg, ppos) and
viableParam(call, sc, ppos, _) and
sc.clearsContent(ppos, c)
)
}
pragma[nomagic] pragma[nomagic]
private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg) { private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg) {
exists(ParameterPosition ppos, SummarizedCallable sc | exists(ParameterPosition ppos, SummarizedCallable sc |
@@ -752,6 +760,27 @@ module Private {
) )
} }
/**
* Holds if use-use flow starting from `arg` should be prohibited.
*
* This is the case when `arg` is the argument of a call that targets a
* flow summary where the corresponding parameter either clears contents
* or expects contents.
*/
pragma[nomagic]
predicate prohibitsUseUseFlow(ArgNode arg) {
exists(ParamNode p, Node mid, ParameterPosition ppos, Node ret |
p = summaryArgParam0(_, arg) and
p.isParameterOf(_, ppos) and
summaryLocalStep(p, mid, true) and
summaryLocalStep(mid, ret, true) and
isParameterPostUpdate(ret, _, ppos)
|
summaryClearsContent(mid, _) or
summaryExpectsContent(mid, _)
)
}
pragma[nomagic] pragma[nomagic]
private ParamNode summaryArgParam(ArgNode arg, ReturnKindExt rk, OutNodeExt out) { private ParamNode summaryArgParam(ArgNode arg, ReturnKindExt rk, OutNodeExt out) {
exists(DataFlowCall call | exists(DataFlowCall call |
@@ -1152,6 +1181,10 @@ module Private {
Private::Steps::summaryClearsContent(a.asNode(), c) and Private::Steps::summaryClearsContent(a.asNode(), c) and
b = a and b = a and
value = "clear (" + c + ")" value = "clear (" + c + ")"
or
Private::Steps::summaryExpectsContent(a.asNode(), c) and
b = a and
value = "expect (" + c + ")"
) )
or or
summaryPostUpdateNode(b.asNode(), a.asNode()) and summaryPostUpdateNode(b.asNode(), a.asNode()) and