@@ -71,27 +71,40 @@ private string canonical_name(API::Node flag) {
71
71
* A type tracker for regular expression flag names. Holds if the result is a node that may refer
72
72
* to the `re` flag with the canonical name `flag_name`
73
73
*/
74
- private DataFlow:: Node re_flag_tracker ( string flag_name , DataFlow:: TypeTracker t ) {
74
+ private DataFlow:: LocalSourceNode re_flag_tracker ( string flag_name , DataFlow:: TypeTracker t ) {
75
75
t .start ( ) and
76
76
exists ( API:: Node flag | flag_name = canonical_name ( flag ) and result = flag .getAUse ( ) )
77
77
or
78
- exists ( BinaryExprNode binop |
78
+ exists ( BinaryExprNode binop , DataFlow:: Node operand |
79
+ operand .getALocalSource ( ) = re_flag_tracker ( flag_name , t .continue ( ) ) and
80
+ operand .asCfgNode ( ) = binop .getAnOperand ( ) and
79
81
( binop .getOp ( ) instanceof BitOr or binop .getOp ( ) instanceof Add ) and
80
- binop .getAnOperand ( ) = re_flag_tracker ( flag_name , t .continue ( ) ) .asCfgNode ( ) and
81
82
result .asCfgNode ( ) = binop
82
83
)
83
84
or
84
- exists ( DataFlow:: TypeTracker t2 , DataFlow:: Node prev | prev = re_flag_tracker ( flag_name , t2 ) |
85
- t2 = t .smallstep ( prev , result )
85
+ // Due to bad performance when using normal setup with `re_flag_tracker(t2, attr_name).track(t2, t)`
86
+ // we have inlined that code and forced a join
87
+ exists ( DataFlow:: TypeTracker t2 |
88
+ exists ( DataFlow:: StepSummary summary |
89
+ re_flag_tracker_first_join ( t2 , flag_name , result , summary ) and
90
+ t = t2 .append ( summary )
91
+ )
86
92
)
87
93
}
88
94
95
+ pragma [ nomagic]
96
+ private predicate re_flag_tracker_first_join (
97
+ DataFlow:: TypeTracker t2 , string flag_name , DataFlow:: Node res , DataFlow:: StepSummary summary
98
+ ) {
99
+ DataFlow:: StepSummary:: step ( re_flag_tracker ( flag_name , t2 ) , res , summary )
100
+ }
101
+
89
102
/**
90
103
* A type tracker for regular expression flag names. Holds if the result is a node that may refer
91
104
* to the `re` flag with the canonical name `flag_name`
92
105
*/
93
106
private DataFlow:: Node re_flag_tracker ( string flag_name ) {
94
- result = re_flag_tracker ( flag_name , DataFlow:: TypeTracker:: end ( ) )
107
+ re_flag_tracker ( flag_name , DataFlow:: TypeTracker:: end ( ) ) . flowsTo ( result )
95
108
}
96
109
97
110
/** Gets a regular expression mode flag associated with the given data flow node. */
0 commit comments