@@ -66,6 +66,8 @@ module SsaFlow {
66
66
result = TThisParameterNode ( p .asThis ( ) )
67
67
or
68
68
result = TPipelineParameterNode ( p .asPipelineParameter ( ) )
69
+ or
70
+ result = TPipelineByPropertyNameParameterNode ( p .asPipelineByPropertyNameParameter ( ) )
69
71
}
70
72
71
73
/** Gets the SSA node corresponding to the PowerShell node `n`. */
@@ -83,6 +85,16 @@ module SsaFlow {
83
85
.definesAt ( pb .getPipelineIteratorVariable ( ) , bb , i )
84
86
)
85
87
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
86
98
result .( Impl:: ExprPostUpdateNode ) .getExpr ( ) = n .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( )
87
99
or
88
100
n = toParameterNode ( result .( Impl:: ParameterNode ) .getParameter ( ) )
@@ -145,13 +157,16 @@ module LocalFlow {
145
157
nodeTo .( ReturnNodeImpl ) .getCfgScope ( ) = scriptBlock .getAstNode ( )
146
158
)
147
159
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 )
154
165
)
166
+ or
167
+ nodeTo .( PreProcessNode ) .getProcessBlock ( ) .getPipelineVariableAccess ( ) = nodeFrom .asExpr ( )
168
+ or
169
+ nodeTo .( ProcessNode ) .getProcessBlock ( ) = nodeFrom .( PreProcessNode ) .getProcessBlock ( )
155
170
}
156
171
157
172
predicate flowSummaryLocalStep (
@@ -179,12 +194,6 @@ module VariableCapture {
179
194
// TODO
180
195
}
181
196
182
- private predicate isProcessPropertyByNameNode (
183
- PipelineByPropertyNameIteratorVariable iter , ProcessBlock pb
184
- ) {
185
- pb = iter .getProcessBlock ( )
186
- }
187
-
188
197
/** A collection of cached types and predicates to be evaluated in the same stage. */
189
198
cached
190
199
private module Cached {
@@ -198,8 +207,6 @@ private module Cached {
198
207
TThisParameterNode ( Method m ) or
199
208
TPipelineByPropertyNameParameterNode ( PipelineByPropertyNameParameter p ) or
200
209
TPipelineParameterNode ( PipelineParameter p ) or
201
- TPrePipelineArgumentNode ( CfgNodes:: ExprNodes:: PipelineArgumentCfgNode n ) or
202
- TPipelineArgumentNode ( CfgNodes:: ExprNodes:: PipelineArgumentCfgNode n ) or
203
210
TExprPostUpdateNode ( CfgNodes:: ExprCfgNode n ) {
204
211
n instanceof CfgNodes:: ExprNodes:: ArgumentCfgNode
205
212
or
@@ -220,9 +227,13 @@ private module Cached {
220
227
blockMayReturnMultipleValues ( scriptBlock )
221
228
} or
222
229
TReturnNodeImpl ( CfgScope scope ) or
230
+ TPreProcessNode ( CfgNodes:: ProcessBlockCfgNode process ) or
223
231
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 ( )
226
237
} or
227
238
TScriptBlockNode ( ScriptBlock scriptBlock ) or
228
239
TForbiddenRecursionGuard ( ) {
@@ -642,10 +653,10 @@ private module ParameterNodes {
642
653
643
654
PipelineByPropertyNameParameterNode ( ) { this = TPipelineByPropertyNameParameterNode ( parameter ) }
644
655
645
- override PipelineParameter getParameter ( ) { result = parameter }
656
+ override PipelineByPropertyNameParameter getParameter ( ) { result = parameter }
646
657
647
658
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
649
660
c .asCfgScope ( ) = parameter .getEnclosingScope ( )
650
661
}
651
662
@@ -709,22 +720,6 @@ abstract class ArgumentNode extends Node {
709
720
final DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
710
721
}
711
722
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
-
728
723
module ArgumentNodes {
729
724
class ExplicitArgumentNode extends ArgumentNode {
730
725
CfgNodes:: ExprNodes:: ArgumentCfgNode arg ;
@@ -768,31 +763,23 @@ module ArgumentNodes {
768
763
}
769
764
}
770
765
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
+ }
783
770
784
- CfgNodes:: ExprNodes:: PipelineArgumentCfgNode getPipelineArgument ( ) { result = e }
785
- }
771
+ CfgNodes:: ExprNodes:: PipelineArgumentCfgNode getPipelineArgument ( ) {
772
+ result = super .getExprNode ( )
773
+ }
786
774
787
- class PipelineArgumentNode extends ArgumentNode instanceof PipelineArgumentNodeImpl {
788
775
override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
789
776
this .sourceArgumentOf ( call .asCall ( ) , pos )
790
777
}
791
778
792
779
override predicate sourceArgumentOf (
793
780
CfgNodes:: ExprNodes:: CallExprCfgNode call , ArgumentPosition pos
794
781
) {
795
- call = super .getPipelineArgument ( ) .getCall ( ) and
782
+ call = this .getPipelineArgument ( ) .getCall ( ) and
796
783
pos .isPipeline ( )
797
784
}
798
785
}
@@ -981,9 +968,9 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
981
968
)
982
969
or
983
970
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 )
987
974
)
988
975
or
989
976
FlowSummaryImpl:: Private:: Steps:: summaryStoreStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , c ,
@@ -1021,27 +1008,24 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
1021
1008
c .isSingleton ( any ( Content:: KnownElementContent ec | exists ( ec .getIndex ( ) .asInt ( ) ) ) )
1022
1009
)
1023
1010
or
1024
- c .isAnyElement ( ) and
1011
+ c .isAnyPositional ( ) and
1025
1012
exists ( CfgNodes:: ProcessBlockCfgNode processBlock |
1026
1013
processBlock .getPipelineVariableAccess ( ) = node1 .asExpr ( ) and
1027
1014
node2 = TProcessNode ( processBlock )
1028
1015
)
1029
1016
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 )
1038
1022
)
1039
1023
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 )
1045
1029
)
1046
1030
or
1047
1031
FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , c ,
@@ -1062,8 +1046,11 @@ predicate clearsContent(Node n, ContentSet c) {
1062
1046
n = TPreReturnNodeImpl ( _, false ) and
1063
1047
c .isAnyElement ( )
1064
1048
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
1067
1054
}
1068
1055
1069
1056
/**
@@ -1078,9 +1065,6 @@ predicate expectsContent(Node n, ContentSet c) {
1078
1065
or
1079
1066
n = TImplicitWrapNode ( _, false ) and
1080
1067
c .isSingleton ( any ( Content:: UnknownElementContent ec ) )
1081
- or
1082
- n instanceof PipelineArgumentNode and
1083
- c .isAnyPositional ( )
1084
1068
}
1085
1069
1086
1070
class DataFlowType extends TDataFlowType {
@@ -1210,6 +1194,22 @@ private class ReturnNodeImpl extends TReturnNodeImpl, NodeImpl {
1210
1194
override predicate nodeIsHidden ( ) { any ( ) }
1211
1195
}
1212
1196
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
+
1213
1213
private class ProcessNode extends TProcessNode , NodeImpl {
1214
1214
CfgNodes:: ProcessBlockCfgNode process ;
1215
1215
@@ -1230,26 +1230,53 @@ private class ProcessNode extends TProcessNode, NodeImpl {
1230
1230
CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) { result = process }
1231
1231
}
1232
1232
1233
- private class ProcessPropertyByNameNode extends TProcessPropertyByNameNode , NodeImpl {
1234
- private PipelineByPropertyNameIteratorVariable iter ;
1233
+ private class PreProcessPropertyByNameNode extends TPreProcessPropertyByNameNode , NodeImpl {
1234
+ private CfgNodes :: ExprNodes :: VarReadAccessCfgNode va ;
1235
1235
1236
- ProcessPropertyByNameNode ( ) { this = TProcessPropertyByNameNode ( iter ) }
1236
+ PreProcessPropertyByNameNode ( ) { this = TPreProcessPropertyByNameNode ( va ) }
1237
1237
1238
- PipelineByPropertyNameIteratorVariable getVariable ( ) { result = iter }
1238
+ CfgNodes :: ExprNodes :: VarReadAccessCfgNode getAccess ( ) { result = va }
1239
1239
1240
- override CfgScope getCfgScope ( ) { result = iter . getDeclaringScope ( ) }
1240
+ override CfgScope getCfgScope ( ) { result = va . getScope ( ) }
1241
1241
1242
- override Location getLocationImpl ( ) { result = iter .getLocation ( ) }
1242
+ override Location getLocationImpl ( ) { result = this . getProcessBlock ( ) .getLocation ( ) }
1243
1243
1244
- override string toStringImpl ( ) { result = "process node for " + iter .toString ( ) }
1244
+ override string toStringImpl ( ) { result = "pre- process node for " + va .toString ( ) }
1245
1245
1246
1246
override predicate nodeIsHidden ( ) { any ( ) }
1247
1247
1248
1248
CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) {
1249
- isProcessPropertyByNameNode ( iter , result .getAstNode ( ) )
1249
+ result .getAPipelineByPropertyNameParameterAccess ( ) = va
1250
1250
}
1251
1251
}
1252
1252
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
+
1253
1280
class ScriptBlockNode extends TScriptBlockNode , NodeImpl {
1254
1281
private ScriptBlock scriptBlock ;
1255
1282
0 commit comments