@@ -473,27 +473,46 @@ abstract class RegexString extends StringLiteral {
473
473
}
474
474
475
475
/**
476
- * Holds if a parse mode starts between `start` and `end`.
476
+ * Holds if the initial part of a parse mode, not containing any
477
+ * mode characters is between `start` and `end`.
477
478
*/
478
- private predicate flagGroupStart ( int start , int end ) {
479
+ private predicate flagGroupStartNoModes ( int start , int end ) {
479
480
this .isGroupStart ( start ) and
480
481
this .getChar ( start + 1 ) = "?" and
481
482
this .getChar ( start + 2 ) in [ "i" , "m" , "s" , "u" , "x" , "U" ] and
482
483
end = start + 2
483
484
}
484
485
485
486
/**
486
- * Holds if a parse mode group is between `start` and `end`, and includes the
487
- * mode flag `c`. For example the following span, with mode flag `i`:
487
+ * Holds if `pos` contains a mode character from the
488
+ * flag group starting at `start`.
489
+ */
490
+ private predicate modeCharacter ( int start , int pos ) {
491
+ this .flagGroupStartNoModes ( start , pos )
492
+ or
493
+ this .modeCharacter ( start , pos - 1 ) and
494
+ this .getChar ( pos ) in [ "i" , "m" , "s" , "u" , "x" , "U" ]
495
+ }
496
+
497
+ /**
498
+ * Holds if a parse mode group is between `start` and `end`.
499
+ */
500
+ private predicate flagGroupStart ( int start , int end ) {
501
+ this .flagGroupStartNoModes ( start , _) and
502
+ end = max ( int i | this .modeCharacter ( start , i ) | i + 1 )
503
+ }
504
+
505
+ /**
506
+ * Holds if a parse mode group of this regex includes the mode flag `c`.
507
+ * For example the following parse mode group, with mode flag `i`:
488
508
* ```
489
509
* (?i)
490
510
* ```
491
511
*/
492
- private predicate flagGroup ( int start , int end , string c ) {
493
- exists ( int inStart , int inEnd |
494
- this .flagGroupStart ( start , inStart ) and
495
- this .groupContents ( start , end , inStart , inEnd ) and
496
- this .getChar ( [ inStart .. inEnd - 1 ] ) = c
512
+ private predicate flag ( string c ) {
513
+ exists ( int pos |
514
+ this .modeCharacter ( _, pos ) and
515
+ this .getChar ( pos ) = c
497
516
)
498
517
}
499
518
@@ -502,7 +521,7 @@ abstract class RegexString extends StringLiteral {
502
521
* it is defined by a prefix.
503
522
*/
504
523
string getModeFromPrefix ( ) {
505
- exists ( string c | this .flagGroup ( _ , _ , c ) |
524
+ exists ( string c | this .flag ( c ) |
506
525
c = "i" and result = "IGNORECASE"
507
526
or
508
527
c = "m" and result = "MULTILINE"
0 commit comments