Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Make FunctionOutput.isResult(0) and CallNode.getResult(0) match single results#157

Merged
max-schaefer merged 10 commits intogithub:masterfrom
owen-mc:isresult-consistency
May 29, 2020
Merged

Make FunctionOutput.isResult(0) and CallNode.getResult(0) match single results#157
max-schaefer merged 10 commits intogithub:masterfrom
owen-mc:isresult-consistency

Conversation

@owen-mc
Copy link
Contributor

@owen-mc owen-mc commented May 27, 2020

Resolves #146

Note that FunctionOutput.isResult() and CallNode.getResult() do not match anything when there is more than one result. I think this is less confusing and error-prone than the alternative.

@owen-mc owen-mc requested review from a team and max-schaefer and removed request for max-schaefer May 27, 2020 09:30
@owen-mc
Copy link
Contributor Author

owen-mc commented May 27, 2020

The commit "Make FunctionOutput.isResult(0) match single results" is making tests for ReflectedXss fail. I'm looking into why.

Copy link
Contributor

@max-schaefer max-schaefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo minor suggestions and the test failure.


override predicate isResult(int i) { i = index and i >= 0 }
override predicate isResult(int i) {
index = -1 and i = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps do i = 0 and isResult() instead? Doesn't make a difference here, but nicely parallels the other changes.


override predicate isResult(int i) { i = index and i >= 0 }
override predicate isResult(int i) {
index = -1 and i = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i = 0 and isResult()

/** Gets the data-flow node corresponding to the `i`th result of this call. */
Node getResult(int i) { result = extractTupleElement(this, i) }
Node getResult(int i) {
not getType() instanceof TupleType and i = 0 and result = this
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
not getType() instanceof TupleType and i = 0 and result = this
i = 0 and result = getResult()

@@ -328,7 +328,11 @@ class CallNode extends ExprNode {
FunctionNode getCallback(int i) { result.getASuccessor*() = this.getArgument(i) }

/** Gets the data-flow node corresponding to the `i`th result of this call. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps mention here that if there is a single result, that is considered to be the 0th result.

@sauyon
Copy link
Contributor

sauyon commented May 27, 2020

I think it would be a bit cleaner to just remove the index = -1 here. Is there some value in having different models of the one and only result and the first result?

TInResult(int index) {
// the one and only result
index = -1
or
// one among several results
exists(SignatureType s | exists(s.getResultType(index)))
}

I also think it would make sense to have a getAResult analagous to getAParameter.

@max-schaefer
Copy link
Contributor

Is there some value in having different models of the one and only result and the first result?

I think it's worth having both, for completeness and analogy with the two getResult predicates, and also as an extra bit of documentation.

I also think it would make sense to have a getAResult analagous to getAParameter.

Seconded.

@owen-mc
Copy link
Contributor Author

owen-mc commented May 28, 2020

@sauyon If we don't have a separate model for "the one and only result" then we can't make it that getResult() does not match anything if there is more than one result, which I think might catch some errors.

@owen-mc owen-mc force-pushed the isresult-consistency branch from 8b208f8 to bbce7d1 Compare May 28, 2020 12:07
if nr = 1 then kind = TSingleReturn() else kind = TMultiReturn(i)
)
}
ReturnNode() { exists(int nr | nr = fd.getType().getNumResult() | kind = MkReturnKind(i)) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need nr?

Copy link
Contributor

@max-schaefer max-schaefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more suggestion, otherwise LGTM. I'll start an evaluation.

override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
inp.isParameter(_) and
(outp.isResult() or outp.isResult(_))
outp.isResult(_)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@max-schaefer max-schaefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evaluation showed no regressions.

@max-schaefer max-schaefer merged commit b37bdec into github:master May 29, 2020
@gagliardetto
Copy link
Contributor

Thank you! 👏

@owen-mc owen-mc deleted the isresult-consistency branch May 29, 2020 16:45
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TaintTracking::FunctionModel: FunctionOutput.isResult() does not correspond to FunctionOutput.isResult(0)

4 participants