@@ -66,6 +66,8 @@ module SsaFlow {
6666 result = TThisParameterNode ( p .asThis ( ) )
6767 or
6868 result = TPipelineParameterNode ( p .asPipelineParameter ( ) )
69+ or
70+ result = TPipelineByPropertyNameParameterNode ( p .asPipelineByPropertyNameParameter ( ) )
6971 }
7072
7173 /** Gets the SSA node corresponding to the PowerShell node `n`. */
@@ -83,6 +85,16 @@ module SsaFlow {
8385 .definesAt ( pb .getPipelineIteratorVariable ( ) , bb , i )
8486 )
8587 or
88+ exists (
89+ BasicBlock bb , int i , PipelineByPropertyNameParameter p , ProcessPropertyByNameNode pbNode
90+ |
91+ pbNode = n and
92+ pbNode .hasRead ( ) and
93+ pbNode .getParameter ( ) = p and
94+ bb .getNode ( i ) = pbNode .getProcessBlock ( ) and
95+ result .( Impl:: SsaDefinitionNode ) .getDefinition ( ) .definesAt ( p .getIteratorVariable ( ) , bb , i )
96+ )
97+ or
8698 result .( Impl:: ExprPostUpdateNode ) .getExpr ( ) = n .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( )
8799 or
88100 n = toParameterNode ( result .( Impl:: ParameterNode ) .getParameter ( ) )
@@ -145,13 +157,16 @@ module LocalFlow {
145157 nodeTo .( ReturnNodeImpl ) .getCfgScope ( ) = scriptBlock .getAstNode ( )
146158 )
147159 or
148- exists ( CfgNodes:: ExprNodes:: PipelineArgumentCfgNode e | nodeFrom .asExpr ( ) = e |
149- // If we are not already tracking as element content
150- nodeTo = TPrePipelineArgumentNode ( e )
151- or
152- // If we are already tracking an element content
153- nodeTo = TPipelineArgumentNode ( e )
160+ nodeTo .( PreProcessPropertyByNameNode ) .getAccess ( ) = nodeFrom .asExpr ( )
161+ or
162+ exists ( PreProcessPropertyByNameNode pbNode |
163+ pbNode = nodeFrom and
164+ nodeTo = TProcessPropertyByNameNode ( pbNode .getAccess ( ) .getVariable ( ) , false )
154165 )
166+ or
167+ nodeTo .( PreProcessNode ) .getProcessBlock ( ) .getPipelineVariableAccess ( ) = nodeFrom .asExpr ( )
168+ or
169+ nodeTo .( ProcessNode ) .getProcessBlock ( ) = nodeFrom .( PreProcessNode ) .getProcessBlock ( )
155170 }
156171
157172 predicate flowSummaryLocalStep (
@@ -179,12 +194,6 @@ module VariableCapture {
179194 // TODO
180195}
181196
182- private predicate isProcessPropertyByNameNode (
183- PipelineByPropertyNameIteratorVariable iter , ProcessBlock pb
184- ) {
185- pb = iter .getProcessBlock ( )
186- }
187-
188197/** A collection of cached types and predicates to be evaluated in the same stage. */
189198cached
190199private module Cached {
@@ -198,8 +207,6 @@ private module Cached {
198207 TThisParameterNode ( Method m ) or
199208 TPipelineByPropertyNameParameterNode ( PipelineByPropertyNameParameter p ) or
200209 TPipelineParameterNode ( PipelineParameter p ) or
201- TPrePipelineArgumentNode ( CfgNodes:: ExprNodes:: PipelineArgumentCfgNode n ) or
202- TPipelineArgumentNode ( CfgNodes:: ExprNodes:: PipelineArgumentCfgNode n ) or
203210 TExprPostUpdateNode ( CfgNodes:: ExprCfgNode n ) {
204211 n instanceof CfgNodes:: ExprNodes:: ArgumentCfgNode
205212 or
@@ -220,9 +227,13 @@ private module Cached {
220227 blockMayReturnMultipleValues ( scriptBlock )
221228 } or
222229 TReturnNodeImpl ( CfgScope scope ) or
230+ TPreProcessNode ( CfgNodes:: ProcessBlockCfgNode process ) or
223231 TProcessNode ( CfgNodes:: ProcessBlockCfgNode process ) or
224- TProcessPropertyByNameNode ( PipelineByPropertyNameIteratorVariable iter ) {
225- isProcessPropertyByNameNode ( iter , _)
232+ TPreProcessPropertyByNameNode ( CfgNodes:: ExprNodes:: VarReadAccessCfgNode va ) {
233+ any ( CfgNodes:: ProcessBlockCfgNode pb ) .getAPipelineByPropertyNameParameterAccess ( ) = va
234+ } or
235+ TProcessPropertyByNameNode ( PipelineByPropertyNameParameter p , Boolean hasRead ) {
236+ p .getDeclaringScope ( ) = any ( ProcessBlock pb ) .getScriptBlock ( )
226237 } or
227238 TScriptBlockNode ( ScriptBlock scriptBlock ) or
228239 TForbiddenRecursionGuard ( ) {
@@ -642,10 +653,10 @@ private module ParameterNodes {
642653
643654 PipelineByPropertyNameParameterNode ( ) { this = TPipelineByPropertyNameParameterNode ( parameter ) }
644655
645- override PipelineParameter getParameter ( ) { result = parameter }
656+ override PipelineByPropertyNameParameter getParameter ( ) { result = parameter }
646657
647658 override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
648- pos .isPipeline ( ) and // what about when it is applied as a normal parameter?
659+ pos .isPipeline ( ) and
649660 c .asCfgScope ( ) = parameter .getEnclosingScope ( )
650661 }
651662
@@ -709,22 +720,6 @@ abstract class ArgumentNode extends Node {
709720 final DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
710721}
711722
712- class PrePipelineArgumentNodeImpl extends NodeImpl , TPrePipelineArgumentNode {
713- CfgNodes:: ExprNodes:: PipelineArgumentCfgNode e ;
714-
715- PrePipelineArgumentNodeImpl ( ) { this = TPrePipelineArgumentNode ( e ) }
716-
717- final override CfgScope getCfgScope ( ) { result = e .getScope ( ) }
718-
719- final override Location getLocationImpl ( ) { result = e .getLocation ( ) }
720-
721- final override string toStringImpl ( ) { result = "[pre pipeline] " + e .toString ( ) }
722-
723- final override predicate nodeIsHidden ( ) { any ( ) }
724-
725- CfgNodes:: ExprNodes:: PipelineArgumentCfgNode getPipelineArgument ( ) { result = e }
726- }
727-
728723module ArgumentNodes {
729724 class ExplicitArgumentNode extends ArgumentNode {
730725 CfgNodes:: ExprNodes:: ArgumentCfgNode arg ;
@@ -768,31 +763,23 @@ module ArgumentNodes {
768763 }
769764 }
770765
771- class PipelineArgumentNodeImpl extends NodeImpl , TPipelineArgumentNode {
772- CfgNodes:: ExprNodes:: PipelineArgumentCfgNode e ;
773-
774- PipelineArgumentNodeImpl ( ) { this = TPipelineArgumentNode ( e ) }
775-
776- final override CfgScope getCfgScope ( ) { result = e .getScope ( ) }
777-
778- final override Location getLocationImpl ( ) { result = e .getLocation ( ) }
779-
780- final override string toStringImpl ( ) { result = e .toString ( ) }
781-
782- final override predicate nodeIsHidden ( ) { none ( ) }
766+ class PipelineArgumentNode extends ArgumentNode instanceof ExprNode {
767+ PipelineArgumentNode ( ) {
768+ this .getExprNode ( ) instanceof CfgNodes:: ExprNodes:: PipelineArgumentCfgNode
769+ }
783770
784- CfgNodes:: ExprNodes:: PipelineArgumentCfgNode getPipelineArgument ( ) { result = e }
785- }
771+ CfgNodes:: ExprNodes:: PipelineArgumentCfgNode getPipelineArgument ( ) {
772+ result = super .getExprNode ( )
773+ }
786774
787- class PipelineArgumentNode extends ArgumentNode instanceof PipelineArgumentNodeImpl {
788775 override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
789776 this .sourceArgumentOf ( call .asCall ( ) , pos )
790777 }
791778
792779 override predicate sourceArgumentOf (
793780 CfgNodes:: ExprNodes:: CallExprCfgNode call , ArgumentPosition pos
794781 ) {
795- call = super .getPipelineArgument ( ) .getCall ( ) and
782+ call = this .getPipelineArgument ( ) .getCall ( ) and
796783 pos .isPipeline ( )
797784 }
798785 }
@@ -981,9 +968,9 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
981968 )
982969 or
983970 c .isUnknownPositionalContent ( ) and
984- exists ( CfgNodes:: ExprNodes :: PipelineArgumentCfgNode arg |
985- node1 = TPrePipelineArgumentNode ( arg ) and
986- node2 = TPipelineArgumentNode ( arg )
971+ exists ( CfgNodes:: ProcessBlockCfgNode process |
972+ node1 = TPreProcessNode ( process ) and
973+ node2 = TProcessNode ( process )
987974 )
988975 or
989976 FlowSummaryImpl:: Private:: Steps:: summaryStoreStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , c ,
@@ -1021,27 +1008,24 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
10211008 c .isSingleton ( any ( Content:: KnownElementContent ec | exists ( ec .getIndex ( ) .asInt ( ) ) ) )
10221009 )
10231010 or
1024- c .isAnyElement ( ) and
1011+ c .isAnyPositional ( ) and
10251012 exists ( CfgNodes:: ProcessBlockCfgNode processBlock |
10261013 processBlock .getPipelineVariableAccess ( ) = node1 .asExpr ( ) and
10271014 node2 = TProcessNode ( processBlock )
10281015 )
10291016 or
1030- exists (
1031- Content:: KnownElementContent ec , PipelineByPropertyNameParameter p , SsaImpl:: DefinitionExt def
1032- |
1033- c .isSingleton ( ec ) and
1034- p .getIteratorVariable ( ) = node1 .( ProcessPropertyByNameNode ) .getVariable ( ) and
1035- p .getName ( ) = ec .getIndex ( ) .asString ( ) and
1036- def .getSourceVariable ( ) = p .getIteratorVariable ( ) and
1037- SsaImpl:: firstRead ( def , node2 .asExpr ( ) )
1017+ c .isAnyPositional ( ) and
1018+ exists ( CfgNodes:: ProcessBlockCfgNode pb , CfgNodes:: ExprNodes:: VarReadAccessCfgNode va |
1019+ va = pb .getAPipelineByPropertyNameParameterAccess ( ) and
1020+ node1 .asExpr ( ) = va and
1021+ node2 = TProcessPropertyByNameNode ( va .getVariable ( ) , false )
10381022 )
10391023 or
1040- exists ( Content :: KnownElementContent ec , SsaImpl :: DefinitionExt def |
1041- c .isSingleton ( ec ) and
1042- node1 . ( PipelineByPropertyNameParameterNode ) . getPropertyName ( ) = ec . getIndex ( ) . asString ( ) and
1043- def = SsaImpl :: getParameterDef ( node1 . ( PipelineByPropertyNameParameterNode ) . getParameter ( ) ) and
1044- SsaImpl :: firstRead ( def , node2 . asExpr ( ) )
1024+ exists ( PipelineByPropertyNameParameter p , Content :: KnownElementContent ec |
1025+ c .isKnownOrUnknownElement ( ec ) and
1026+ ec . getIndex ( ) . asString ( ) = p . getPropertyName ( ) and
1027+ node1 = TProcessPropertyByNameNode ( p , false ) and
1028+ node2 = TProcessPropertyByNameNode ( p , true )
10451029 )
10461030 or
10471031 FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , c ,
@@ -1062,8 +1046,11 @@ predicate clearsContent(Node n, ContentSet c) {
10621046 n = TPreReturnNodeImpl ( _, false ) and
10631047 c .isAnyElement ( )
10641048 or
1065- n instanceof PrePipelineArgumentNodeImpl and
1066- c .isAnyPositional ( )
1049+ c .isAnyPositional ( ) and
1050+ n instanceof PreProcessPropertyByNameNode
1051+ or
1052+ c .isAnyPositional ( ) and
1053+ n instanceof PreProcessNode
10671054}
10681055
10691056/**
@@ -1078,9 +1065,6 @@ predicate expectsContent(Node n, ContentSet c) {
10781065 or
10791066 n = TImplicitWrapNode ( _, false ) and
10801067 c .isSingleton ( any ( Content:: UnknownElementContent ec ) )
1081- or
1082- n instanceof PipelineArgumentNode and
1083- c .isAnyPositional ( )
10841068}
10851069
10861070class DataFlowType extends TDataFlowType {
@@ -1210,6 +1194,22 @@ private class ReturnNodeImpl extends TReturnNodeImpl, NodeImpl {
12101194 override predicate nodeIsHidden ( ) { any ( ) }
12111195}
12121196
1197+ private class PreProcessNode extends TPreProcessNode , NodeImpl {
1198+ CfgNodes:: ProcessBlockCfgNode process ;
1199+
1200+ PreProcessNode ( ) { this = TPreProcessNode ( process ) }
1201+
1202+ override CfgScope getCfgScope ( ) { result = process .getScope ( ) }
1203+
1204+ override Location getLocationImpl ( ) { result = process .getLocation ( ) }
1205+
1206+ override string toStringImpl ( ) { result = "pre-process node for " + process .toString ( ) }
1207+
1208+ override predicate nodeIsHidden ( ) { any ( ) }
1209+
1210+ CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) { result = process }
1211+ }
1212+
12131213private class ProcessNode extends TProcessNode , NodeImpl {
12141214 CfgNodes:: ProcessBlockCfgNode process ;
12151215
@@ -1230,26 +1230,53 @@ private class ProcessNode extends TProcessNode, NodeImpl {
12301230 CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) { result = process }
12311231}
12321232
1233- private class ProcessPropertyByNameNode extends TProcessPropertyByNameNode , NodeImpl {
1234- private PipelineByPropertyNameIteratorVariable iter ;
1233+ private class PreProcessPropertyByNameNode extends TPreProcessPropertyByNameNode , NodeImpl {
1234+ private CfgNodes :: ExprNodes :: VarReadAccessCfgNode va ;
12351235
1236- ProcessPropertyByNameNode ( ) { this = TProcessPropertyByNameNode ( iter ) }
1236+ PreProcessPropertyByNameNode ( ) { this = TPreProcessPropertyByNameNode ( va ) }
12371237
1238- PipelineByPropertyNameIteratorVariable getVariable ( ) { result = iter }
1238+ CfgNodes :: ExprNodes :: VarReadAccessCfgNode getAccess ( ) { result = va }
12391239
1240- override CfgScope getCfgScope ( ) { result = iter . getDeclaringScope ( ) }
1240+ override CfgScope getCfgScope ( ) { result = va . getScope ( ) }
12411241
1242- override Location getLocationImpl ( ) { result = iter .getLocation ( ) }
1242+ override Location getLocationImpl ( ) { result = this . getProcessBlock ( ) .getLocation ( ) }
12431243
1244- override string toStringImpl ( ) { result = "process node for " + iter .toString ( ) }
1244+ override string toStringImpl ( ) { result = "pre- process node for " + va .toString ( ) }
12451245
12461246 override predicate nodeIsHidden ( ) { any ( ) }
12471247
12481248 CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) {
1249- isProcessPropertyByNameNode ( iter , result .getAstNode ( ) )
1249+ result .getAPipelineByPropertyNameParameterAccess ( ) = va
12501250 }
12511251}
12521252
1253+ private class ProcessPropertyByNameNode extends TProcessPropertyByNameNode , NodeImpl {
1254+ private PipelineByPropertyNameParameter p ;
1255+ private boolean hasRead ;
1256+
1257+ ProcessPropertyByNameNode ( ) { this = TProcessPropertyByNameNode ( p , hasRead ) }
1258+
1259+ PipelineByPropertyNameParameter getParameter ( ) { result = p }
1260+
1261+ override CfgScope getCfgScope ( ) { result = p .getDeclaringScope ( ) }
1262+
1263+ override Location getLocationImpl ( ) { result = this .getProcessBlock ( ) .getLocation ( ) }
1264+
1265+ override string toStringImpl ( ) {
1266+ hasRead = false and
1267+ result = "process node for " + p .toString ( )
1268+ or
1269+ hasRead = true and
1270+ result = "[has read] process node for " + p .toString ( )
1271+ }
1272+
1273+ override predicate nodeIsHidden ( ) { any ( ) }
1274+
1275+ CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) { result .getScope ( ) .getAParameter ( ) = p }
1276+
1277+ predicate hasRead ( ) { hasRead = true }
1278+ }
1279+
12531280class ScriptBlockNode extends TScriptBlockNode , NodeImpl {
12541281 private ScriptBlock scriptBlock ;
12551282
0 commit comments