@@ -60,6 +60,65 @@ private class StandardRegexCreation extends RegexCreation {
6060 override DataFlow:: Node getStringInput ( ) { result = input }
6161}
6262
63+ newtype TRegexParseMode =
64+ MkIgnoreCase ( ) or // case insensitive
65+ MkVerbose ( ) or // ignores whitespace and `#` comments within patterns
66+ MkDotAll ( ) or // dot matches all characters, including line terminators
67+ MkMultiLine ( ) or // `^` and `$` also match beginning and end of lines
68+ MkUnicode ( ) // Unicode UAX 29 word boundary mode
69+
70+ class RegexParseMode extends TRegexParseMode {
71+ string toString ( ) {
72+ ( this = MkIgnoreCase ( ) and result = "IGNORECASE" ) or
73+ ( this = MkVerbose ( ) and result = "VERBOSE" ) or
74+ ( this = MkDotAll ( ) and result = "DOTALL" ) or
75+ ( this = MkUnicode ( ) and result = "MULTILINE" ) or
76+ ( this = MkIgnoreCase ( ) and result = "UNICODE" )
77+ }
78+ }
79+
80+ /**
81+ * A unit class for adding additional flow steps for regular expressions.
82+ */
83+ class RegexAdditionalFlowStep extends Unit {
84+ /**
85+ * Holds if the step from `node1` to `node2` should be considered a flow
86+ * step for regular expressions.
87+ */
88+ abstract predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) ;
89+
90+ /**
91+ * Holds if the step from `node1` to `node2` either sets (`isSet` = true)
92+ * or unsets (`isSet` = false) parse mode `mode` for the regular expression.
93+ */
94+ abstract predicate modifiesParseMode ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo , RegexParseMode mode , boolean isSet ) ;
95+ }
96+
97+ /**
98+ * An additional flow step for `Regex` or `NSRegularExpression`.
99+ */
100+ class StandardRegexAdditionalFlowStep extends RegexAdditionalFlowStep {
101+ override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
102+ this .modifiesParseMode ( nodeFrom , nodeTo , _, _)
103+ }
104+
105+ override predicate modifiesParseMode ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo , RegexParseMode mode , boolean isSet )
106+ {
107+ exists ( CallExpr ce |
108+ ce .getStaticTarget ( ) .( Method ) .hasQualifiedName ( "Regex" , "dotMatchesNewlines(_:)" ) and
109+ nodeFrom .asExpr ( ) = ce .getQualifier ( ) and
110+ nodeTo .asExpr ( ) = ce and
111+ mode = MkDotAll ( ) and
112+ // TODO: other methods
113+ // decode the value being set
114+ if ce .getArgument ( 0 ) .getExpr ( ) .( BooleanLiteralExpr ) .getValue ( ) = false then
115+ isSet = false // mode is set to false
116+ else
117+ isSet = true // mode is set to true OR mode is set to default (=true) OR mode is set to an unknown value
118+ )
119+ }
120+ }
121+
63122/**
64123 * A call that evaluates a regular expression. For example, the call to `firstMatch` in:
65124 * ```
0 commit comments