@@ -66,35 +66,53 @@ private CfgNodes::ExprNodes::VariableWriteAccessCfgNode variablesInPattern(
6666 )
6767}
6868
69- /**
70- * Holds if the additional step from `nodeFrom` to `nodeTo` should be included
71- * in all global taint flow configurations.
72- */
7369cached
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+ }
100116}
117+
118+ import Cached
0 commit comments