@@ -71,27 +71,40 @@ private string canonical_name(API::Node flag) {
7171 * A type tracker for regular expression flag names. Holds if the result is a node that may refer
7272 * to the `re` flag with the canonical name `flag_name`
7373 */
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 ) {
7575 t .start ( ) and
7676 exists ( API:: Node flag | flag_name = canonical_name ( flag ) and result = flag .getAUse ( ) )
7777 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
7981 ( binop .getOp ( ) instanceof BitOr or binop .getOp ( ) instanceof Add ) and
80- binop .getAnOperand ( ) = re_flag_tracker ( flag_name , t .continue ( ) ) .asCfgNode ( ) and
8182 result .asCfgNode ( ) = binop
8283 )
8384 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+ )
8692 )
8793}
8894
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+
89102/**
90103 * A type tracker for regular expression flag names. Holds if the result is a node that may refer
91104 * to the `re` flag with the canonical name `flag_name`
92105 */
93106private 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 )
95108}
96109
97110/** Gets a regular expression mode flag associated with the given data flow node. */
0 commit comments