@@ -8,23 +8,56 @@ private import codeql.swift.dataflow.DataFlow
8
8
private import internal.ParseRegex
9
9
private import internal.RegexTracking
10
10
11
+ /**
12
+ * A data flow node whose value may flow to a position where it is interpreted
13
+ * as a part of a regular expression. For example the string literal
14
+ * `"(a|b).*"` in:
15
+ * ```
16
+ * Regex("(a|b).*").firstMatch(in: myString)
17
+ * ```
18
+ */
19
+ abstract class RegexPatternSource extends DataFlow:: Node {
20
+ /**
21
+ * Gets a node where the pattern of this node is parsed as a part of
22
+ * a regular expression.
23
+ */
24
+ abstract DataFlow:: Node getAParse ( ) ;
25
+
26
+ /**
27
+ * Gets the root term of the regular expression parsed from this pattern.
28
+ */
29
+ abstract RegExpTerm getRegExpTerm ( ) ;
30
+ }
31
+
32
+ /**
33
+ * For each `RegexPatternSource` data flow node, the corresponding `Expr` is
34
+ * a `Regex`. This is a simple wrapper to make that happen.
35
+ */
36
+ private class RegexFromRegexPatternSource extends RegExp {
37
+ RegexPatternSource node ;
38
+
39
+ RegexFromRegexPatternSource ( ) { this = node .asExpr ( ) }
40
+ }
41
+
11
42
/**
12
43
* A string literal that is used as a regular expression. For example
13
44
* the string literal `"(a|b).*"` in:
14
45
* ```
15
46
* Regex("(a|b).*").firstMatch(in: myString)
16
47
* ```
17
48
*/
18
- private class ParsedStringRegex extends RegExp , StringLiteralExpr {
49
+ private class ParsedStringRegex extends RegexPatternSource {
50
+ StringLiteralExpr expr ;
19
51
DataFlow:: Node use ;
20
52
21
- ParsedStringRegex ( ) { StringLiteralUseFlow:: flow ( DataFlow:: exprNode ( this ) , use ) }
53
+ ParsedStringRegex ( ) {
54
+ expr = this .asExpr ( ) and
55
+ StringLiteralUseFlow:: flow ( this , use )
56
+ }
22
57
23
- /**
24
- * Gets a dataflow node where this string literal is used as a regular
25
- * expression.
26
- */
27
- DataFlow:: Node getUse ( ) { result = use }
58
+ override DataFlow:: Node getAParse ( ) { result = use }
59
+
60
+ override RegExpTerm getRegExpTerm ( ) { result .getRegExp ( ) = this .asExpr ( ) }
28
61
}
29
62
30
63
/**
@@ -246,11 +279,11 @@ abstract class RegexEval extends CallExpr {
246
279
*/
247
280
RegExp getARegex ( ) {
248
281
// string literal used directly as a regex
249
- result .( ParsedStringRegex ) .getUse ( ) .asExpr ( ) = this .getRegexInput ( )
282
+ DataFlow :: exprNode ( result ) .( ParsedStringRegex ) .getAParse ( ) .asExpr ( ) = this .getRegexInput ( )
250
283
or
251
284
// string literal -> regex object -> use
252
285
exists ( RegexCreation regexCreation |
253
- result .( ParsedStringRegex ) .getUse ( ) = regexCreation .getStringInput ( ) and
286
+ DataFlow :: exprNode ( result ) .( ParsedStringRegex ) .getAParse ( ) = regexCreation .getStringInput ( ) and
254
287
RegexUseFlow:: flow ( regexCreation , DataFlow:: exprNode ( this .getRegexInput ( ) ) )
255
288
)
256
289
}
0 commit comments