Skip to content

Commit ee8c586

Browse files
committed
PS: Use the new library to calculate returned expressions.
1 parent a9861e1 commit ee8c586

File tree

1 file changed

+35
-43
lines changed

1 file changed

+35
-43
lines changed

powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ private import DataFlowDispatch
88
private import SsaImpl as SsaImpl
99
private import FlowSummaryImpl as FlowSummaryImpl
1010
private import semmle.code.powershell.frameworks.data.ModelsAsData
11+
private import PipelineReturns as PipelineReturns
1112

1213
/** Gets the callable in which this node occurs. */
1314
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.(NodeImpl).getEnclosingCallable() }
@@ -87,6 +88,16 @@ module SsaFlow {
8788
}
8889
}
8990

91+
private module ArrayExprFlow {
92+
private module Input implements PipelineReturns::InputSig {
93+
predicate isSource(CfgNodes::AstCfgNode source) {
94+
source = any(CfgNodes::ExprNodes::ArrayExprCfgNode ae).getStmtBlock()
95+
}
96+
}
97+
98+
import PipelineReturns::Make<Input>
99+
}
100+
90101
/** Provides predicates related to local data flow. */
91102
module LocalFlow {
92103
pragma[nomagic]
@@ -184,8 +195,12 @@ private module Cached {
184195
n = any(CfgNodes::ExprNodes::IndexExprCfgNode index).getBase()
185196
} or
186197
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or
187-
TPreReturnNodeImpl(CfgNodes::AstCfgNode n, Boolean isArray) { isMultiReturned(n) } or
188-
TImplicitWrapNode(CfgNodes::AstCfgNode n, Boolean shouldWrap) { isMultiReturned(n) } or
198+
TPreReturnNodeImpl(CfgNodes::ScriptBlockCfgNode scriptBlock, Boolean isArray) {
199+
blockMayReturnMultipleValues(scriptBlock)
200+
} or
201+
TImplicitWrapNode(CfgNodes::ScriptBlockCfgNode scriptBlock, Boolean shouldWrap) {
202+
blockMayReturnMultipleValues(scriptBlock)
203+
} or
189204
TReturnNodeImpl(CfgScope scope) or
190205
TProcessNode(ProcessBlock process) or
191206
TProcessPropertyByNameNode(PipelineByPropertyNameIteratorVariable iter) {
@@ -752,64 +767,41 @@ abstract class ReturnNode extends Node {
752767
abstract ReturnKind getKind();
753768
}
754769

755-
private module EscapeContainer {
756-
private import semmle.code.powershell.internal.AstEscape::Private
770+
private class SummaryReturnNode extends FlowSummaryNode, ReturnNode {
771+
private ReturnKind rk;
757772

758-
private module ReturnContainerInterpreter implements InterpretAstInputSig {
759-
class T = CfgNodes::AstCfgNode;
760-
761-
T interpret(Ast a) { result.(CfgNodes::ExprCfgNode).getExpr() = a } // TODO: Recutse into expr-to-stmt conversions
762-
}
763-
764-
class EscapeContainer extends AstEscape<ReturnContainerInterpreter>::Element {
765-
/** Holds if `n` may be returned multiples times. */
766-
predicate mayBeMultiReturned(CfgNode n) {
767-
n = this.getANode() and
768-
n.getASuccessor+() = n
769-
or
770-
this.getAChild().(EscapeContainer).mayBeMultiReturned(n)
771-
}
772-
}
773+
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) }
773774

774-
private class SummaryReturnNode extends FlowSummaryNode, ReturnNode {
775-
private ReturnKind rk;
776-
777-
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) }
778-
779-
override ReturnKind getKind() { result = rk }
780-
}
775+
override ReturnKind getKind() { result = rk }
781776
}
782777

783778
private module ReturnNodes {
784-
private import EscapeContainer
779+
private CfgNodes::NamedBlockCfgNode getAReturnBlock(CfgNodes::ScriptBlockCfgNode sb) {
780+
result = sb.getBeginBlock()
781+
or
782+
result = sb.getEndBlock()
783+
or
784+
result = sb.getProcessBlock()
785+
}
785786

786-
private predicate isReturnedImpl(CfgNodes::AstCfgNode n, EscapeContainer container) {
787-
container = n.getScope() and
788-
n = container.getAnEscapingElement()
787+
private module CfgScopeReturn implements PipelineReturns::InputSig {
788+
predicate isSource(CfgNodes::AstCfgNode source) { source = getAReturnBlock(_) }
789789
}
790790

791+
private module P = PipelineReturns::Make<CfgScopeReturn>;
792+
791793
/**
792794
* Holds if `n` may be returned, and there are possibly
793795
* more than one return value from the function.
794796
*/
795-
predicate isMultiReturned(CfgNodes::AstCfgNode n) {
796-
exists(EscapeContainer container | isReturnedImpl(n, container) |
797-
strictcount(container.getAnEscapingElement()) > 1
798-
or
799-
container.mayBeMultiReturned(n)
800-
)
797+
predicate blockMayReturnMultipleValues(CfgNodes::ScriptBlockCfgNode scriptBlock) {
798+
P::mayReturnMultipleValues(getAReturnBlock(scriptBlock))
801799
}
802800

803801
/**
804802
* Holds if `n` may be returned.
805803
*/
806-
predicate isReturned(CfgNodes::AstCfgNode n) { isReturnedImpl(n, _) }
807-
808-
/**
809-
* Holds if `n` may be returned, and this is the only value that may be
810-
* returned from the function.
811-
*/
812-
predicate isUniqueReturned(CfgNodes::AstCfgNode n) { isReturned(n) and not isMultiReturned(n) }
804+
predicate isReturned(CfgNodes::AstCfgNode n) { n = P::getAReturn(_) }
813805

814806
class NormalReturnNode extends ReturnNode instanceof ReturnNodeImpl {
815807
final override NormalReturnKind getKind() { any() }

0 commit comments

Comments
 (0)