@@ -8,23 +8,56 @@ private import codeql.swift.dataflow.DataFlow
88private import internal.ParseRegex
99private import internal.RegexTracking
1010
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+
1142/**
1243 * A string literal that is used as a regular expression. For example
1344 * the string literal `"(a|b).*"` in:
1445 * ```
1546 * Regex("(a|b).*").firstMatch(in: myString)
1647 * ```
1748 */
18- private class ParsedStringRegex extends RegExp , StringLiteralExpr {
49+ private class ParsedStringRegex extends RegexPatternSource {
50+ StringLiteralExpr expr ;
1951 DataFlow:: Node use ;
2052
21- ParsedStringRegex ( ) { StringLiteralUseFlow:: flow ( DataFlow:: exprNode ( this ) , use ) }
53+ ParsedStringRegex ( ) {
54+ expr = this .asExpr ( ) and
55+ StringLiteralUseFlow:: flow ( this , use )
56+ }
2257
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 ( ) }
2861}
2962
3063/**
@@ -246,11 +279,11 @@ abstract class RegexEval extends CallExpr {
246279 */
247280 RegExp getARegex ( ) {
248281 // string literal used directly as a regex
249- result .( ParsedStringRegex ) .getUse ( ) .asExpr ( ) = this .getRegexInput ( )
282+ DataFlow :: exprNode ( result ) .( ParsedStringRegex ) .getAParse ( ) .asExpr ( ) = this .getRegexInput ( )
250283 or
251284 // string literal -> regex object -> use
252285 exists ( RegexCreation regexCreation |
253- result .( ParsedStringRegex ) .getUse ( ) = regexCreation .getStringInput ( ) and
286+ DataFlow :: exprNode ( result ) .( ParsedStringRegex ) .getAParse ( ) = regexCreation .getStringInput ( ) and
254287 RegexUseFlow:: flow ( regexCreation , DataFlow:: exprNode ( this .getRegexInput ( ) ) )
255288 )
256289 }
0 commit comments