mirror of
https://github.com/github/codeql.git
synced 2026-03-06 23:56:48 +01:00
Swift: Rework ParsedStringRegex and introduce the needed RegexPatternSource class.
This commit is contained in:
@@ -8,6 +8,37 @@ private import codeql.swift.dataflow.DataFlow
|
||||
private import internal.ParseRegex
|
||||
private import internal.RegexTracking
|
||||
|
||||
/**
|
||||
* A data flow node whose value may flow to a position where it is interpreted
|
||||
* as a part of a regular expression. For example the string literal
|
||||
* `"(a|b).*"` in:
|
||||
* ```
|
||||
* Regex("(a|b).*").firstMatch(in: myString)
|
||||
* ```
|
||||
*/
|
||||
abstract class RegexPatternSource extends DataFlow::Node {
|
||||
/**
|
||||
* Gets a node where the pattern of this node is parsed as a part of
|
||||
* a regular expression.
|
||||
*/
|
||||
abstract DataFlow::Node getAParse();
|
||||
|
||||
/**
|
||||
* Gets the root term of the regular expression parsed from this pattern.
|
||||
*/
|
||||
abstract RegExpTerm getRegExpTerm();
|
||||
}
|
||||
|
||||
/**
|
||||
* For each `RegexPatternSource` data flow node, the corresponding `Expr` is
|
||||
* a `Regex`. This is a simple wrapper to make that happen.
|
||||
*/
|
||||
private class RegexFromRegexPatternSource extends RegExp {
|
||||
RegexPatternSource node;
|
||||
|
||||
RegexFromRegexPatternSource() { this = node.asExpr() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A string literal that is used as a regular expression. For example
|
||||
* the string literal `"(a|b).*"` in:
|
||||
@@ -15,16 +46,18 @@ private import internal.RegexTracking
|
||||
* Regex("(a|b).*").firstMatch(in: myString)
|
||||
* ```
|
||||
*/
|
||||
private class ParsedStringRegex extends RegExp, StringLiteralExpr {
|
||||
private class ParsedStringRegex extends RegexPatternSource {
|
||||
StringLiteralExpr expr;
|
||||
DataFlow::Node use;
|
||||
|
||||
ParsedStringRegex() { StringLiteralUseFlow::flow(DataFlow::exprNode(this), use) }
|
||||
ParsedStringRegex() {
|
||||
expr = this.asExpr() and
|
||||
StringLiteralUseFlow::flow(this, use)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a dataflow node where this string literal is used as a regular
|
||||
* expression.
|
||||
*/
|
||||
DataFlow::Node getUse() { result = use }
|
||||
override DataFlow::Node getAParse() { result = use }
|
||||
|
||||
override RegExpTerm getRegExpTerm() { result.getRegExp() = this.asExpr() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,11 +279,11 @@ abstract class RegexEval extends CallExpr {
|
||||
*/
|
||||
RegExp getARegex() {
|
||||
// string literal used directly as a regex
|
||||
result.(ParsedStringRegex).getUse().asExpr() = this.getRegexInput()
|
||||
DataFlow::exprNode(result).(ParsedStringRegex).getAParse().asExpr() = this.getRegexInput()
|
||||
or
|
||||
// string literal -> regex object -> use
|
||||
exists(RegexCreation regexCreation |
|
||||
result.(ParsedStringRegex).getUse() = regexCreation.getStringInput() and
|
||||
DataFlow::exprNode(result).(ParsedStringRegex).getAParse() = regexCreation.getStringInput() and
|
||||
RegexUseFlow::flow(regexCreation, DataFlow::exprNode(this.getRegexInput()))
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user