diff --git a/swift/ql/lib/codeql/swift/regex/Regex.qll b/swift/ql/lib/codeql/swift/regex/Regex.qll index a14761368e9..e6edd200e6f 100644 --- a/swift/ql/lib/codeql/swift/regex/Regex.qll +++ b/swift/ql/lib/codeql/swift/regex/Regex.qll @@ -28,6 +28,39 @@ private class ParsedStringRegex extends RegExp, StringLiteralExpr { RegexEval getEval() { result = eval } } +/** + * A data-flow node where a regular expression object is created. + */ +abstract class RegexCreation extends DataFlow::Node { + /** + * Gets a dataflow node for the string that the regular expression object is + * created from. + */ + abstract DataFlow::Node getStringInput(); +} + +/** + * A data-flow node where a `Regex` or `NSRegularExpression` object is created. + */ +private class StandardRegexCreation extends RegexCreation { + DataFlow::Node input; + + StandardRegexCreation() { + exists(CallExpr call | + ( + call.getStaticTarget().(Method).hasQualifiedName("Regex", ["init(_:)", "init(_:as:)"]) or + call.getStaticTarget() + .(Method) + .hasQualifiedName("NSRegularExpression", "init(pattern:options:)") + ) and + input.asExpr() = call.getArgument(0).getExpr() and + this.asExpr() = call + ) + } + + override DataFlow::Node getStringInput() { result = input } +} + /** * A call that evaluates a regular expression. For example, the call to `firstMatch` in: * ``` diff --git a/swift/ql/lib/codeql/swift/regex/internal/RegexTracking.qll b/swift/ql/lib/codeql/swift/regex/internal/RegexTracking.qll index 3c1a6e4bc3b..af50cf4cf1e 100644 --- a/swift/ql/lib/codeql/swift/regex/internal/RegexTracking.qll +++ b/swift/ql/lib/codeql/swift/regex/internal/RegexTracking.qll @@ -21,15 +21,9 @@ private module StringLiteralUseConfig implements DataFlow::ConfigSig { predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { // flow through `Regex` initializer, i.e. from a string to a `Regex` object. - exists(CallExpr call | - ( - call.getStaticTarget().(Method).hasQualifiedName("Regex", ["init(_:)", "init(_:as:)"]) or - call.getStaticTarget() - .(Method) - .hasQualifiedName("NSRegularExpression", "init(pattern:options:)") - ) and - nodeFrom.asExpr() = call.getArgument(0).getExpr() and - nodeTo.asExpr() = call + exists(RegexCreation regexCreation | + nodeFrom = regexCreation.getStringInput() and + nodeTo = regexCreation ) } }