@@ -66,35 +66,53 @@ private CfgNodes::ExprNodes::VariableWriteAccessCfgNode variablesInPattern(
66
66
)
67
67
}
68
68
69
- /**
70
- * Holds if the additional step from `nodeFrom` to `nodeTo` should be included
71
- * in all global taint flow configurations.
72
- */
73
69
cached
74
- predicate defaultAdditionalTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
75
- // value of `case` expression into variables in patterns
76
- exists ( CfgNodes:: ExprNodes:: CaseExprCfgNode case , CfgNodes:: ExprNodes:: InClauseCfgNode clause |
77
- nodeFrom .asExpr ( ) = case .getValue ( ) and
78
- clause = case .getBranch ( _) and
79
- nodeTo .( SsaDefinitionNode ) .getDefinition ( ) .getControlFlowNode ( ) =
80
- variablesInPattern ( clause .getPattern ( ) )
81
- )
82
- or
83
- // operation involving `nodeFrom`
84
- exists ( CfgNodes:: ExprNodes:: OperationCfgNode op |
85
- op = nodeTo .asExpr ( ) and
86
- op .getAnOperand ( ) = nodeFrom .asExpr ( ) and
87
- not op .getExpr ( ) instanceof AssignExpr
88
- )
89
- or
90
- // string interpolation of `nodeFrom` into `nodeTo`
91
- nodeFrom .asExpr ( ) =
92
- nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: StringlikeLiteralCfgNode ) .getAComponent ( )
93
- or
94
- FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom , nodeTo , false )
95
- or
96
- // Although flow through arrays is modelled precisely using stores/reads, we still
97
- // allow flow out of a _tainted_ array. This is needed in order to support taint-
98
- // tracking configurations where the source is an array.
99
- readStep ( nodeFrom , any ( DataFlow:: Content:: ArrayElementContent c ) , nodeTo )
70
+ private module Cached {
71
+ /**
72
+ * Holds if the additional step from `nodeFrom` to `nodeTo` should be included
73
+ * in all global taint flow configurations.
74
+ */
75
+ cached
76
+ predicate defaultAdditionalTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
77
+ // value of `case` expression into variables in patterns
78
+ exists ( CfgNodes:: ExprNodes:: CaseExprCfgNode case , CfgNodes:: ExprNodes:: InClauseCfgNode clause |
79
+ nodeFrom .asExpr ( ) = case .getValue ( ) and
80
+ clause = case .getBranch ( _) and
81
+ nodeTo .( SsaDefinitionNode ) .getDefinition ( ) .getControlFlowNode ( ) =
82
+ variablesInPattern ( clause .getPattern ( ) )
83
+ )
84
+ or
85
+ // operation involving `nodeFrom`
86
+ exists ( CfgNodes:: ExprNodes:: OperationCfgNode op |
87
+ op = nodeTo .asExpr ( ) and
88
+ op .getAnOperand ( ) = nodeFrom .asExpr ( ) and
89
+ not op .getExpr ( ) instanceof AssignExpr
90
+ )
91
+ or
92
+ // string interpolation of `nodeFrom` into `nodeTo`
93
+ nodeFrom .asExpr ( ) =
94
+ nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: StringlikeLiteralCfgNode ) .getAComponent ( )
95
+ or
96
+ FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom , nodeTo , false )
97
+ or
98
+ // Although flow through arrays is modelled precisely using stores/reads, we still
99
+ // allow flow out of a _tainted_ array. This is needed in order to support taint-
100
+ // tracking configurations where the source is an array.
101
+ readStep ( nodeFrom , any ( DataFlow:: Content:: ArrayElementContent c ) , nodeTo )
102
+ }
103
+
104
+ /**
105
+ * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
106
+ * (intra-procedural) step.
107
+ */
108
+ cached
109
+ predicate localTaintStepCached ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
110
+ defaultAdditionalTaintStep ( nodeFrom , nodeTo )
111
+ or
112
+ // Simple flow through library code is included in the exposed local
113
+ // step relation, even though flow is technically inter-procedural
114
+ FlowSummaryImpl:: Private:: Steps:: summaryThroughStep ( nodeFrom , nodeTo , false )
115
+ }
100
116
}
117
+
118
+ import Cached
0 commit comments