@@ -8,6 +8,7 @@ private import DataFlowDispatch
8
8
private import SsaImpl as SsaImpl
9
9
private import FlowSummaryImpl as FlowSummaryImpl
10
10
private import semmle.code.powershell.frameworks.data.ModelsAsData
11
+ private import PipelineReturns as PipelineReturns
11
12
12
13
/** Gets the callable in which this node occurs. */
13
14
DataFlowCallable nodeGetEnclosingCallable ( Node n ) { result = n .( NodeImpl ) .getEnclosingCallable ( ) }
@@ -87,6 +88,16 @@ module SsaFlow {
87
88
}
88
89
}
89
90
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
+
90
101
/** Provides predicates related to local data flow. */
91
102
module LocalFlow {
92
103
pragma [ nomagic]
@@ -184,8 +195,12 @@ private module Cached {
184
195
n = any ( CfgNodes:: ExprNodes:: IndexExprCfgNode index ) .getBase ( )
185
196
} or
186
197
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
189
204
TReturnNodeImpl ( CfgScope scope ) or
190
205
TProcessNode ( ProcessBlock process ) or
191
206
TProcessPropertyByNameNode ( PipelineByPropertyNameIteratorVariable iter ) {
@@ -752,64 +767,41 @@ abstract class ReturnNode extends Node {
752
767
abstract ReturnKind getKind ( ) ;
753
768
}
754
769
755
- private module EscapeContainer {
756
- private import semmle.code.powershell.internal.AstEscape :: Private
770
+ private class SummaryReturnNode extends FlowSummaryNode , ReturnNode {
771
+ private ReturnKind rk ;
757
772
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 ) }
773
774
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 }
781
776
}
782
777
783
778
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
+ }
785
786
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 ( _) }
789
789
}
790
790
791
+ private module P = PipelineReturns:: Make< CfgScopeReturn > ;
792
+
791
793
/**
792
794
* Holds if `n` may be returned, and there are possibly
793
795
* more than one return value from the function.
794
796
*/
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 ) )
801
799
}
802
800
803
801
/**
804
802
* Holds if `n` may be returned.
805
803
*/
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 ( _) }
813
805
814
806
class NormalReturnNode extends ReturnNode instanceof ReturnNodeImpl {
815
807
final override NormalReturnKind getKind ( ) { any ( ) }
0 commit comments