Skip to content

Commit 8a5f3e4

Browse files
committed
Swift: Fix an issue with RegexTracking.qll using PotentialRegexEval rather than RegexEval.
1 parent 021ed88 commit 8a5f3e4

File tree

4 files changed

+15
-29
lines changed

4 files changed

+15
-29
lines changed

swift/ql/lib/codeql/swift/regex/Regex.qll

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,12 @@ class RegexEval extends CallExpr instanceof PotentialRegexEval {
316316
*/
317317
Expr getStringInput() { result = this.(PotentialRegexEval).getStringInput().asExpr() }
318318

319+
/**
320+
* Gets a dataflow node for an options input that might contain parse mode
321+
* flags (if any).
322+
*/
323+
DataFlow::Node getAnOptionsInput() { result = this.(PotentialRegexEval).getAnOptionsInput() }
324+
319325
/**
320326
* Gets a regular expression value that is evaluated here (if any can be identified).
321327
*/
@@ -365,7 +371,7 @@ abstract class PotentialRegexEval extends CallExpr {
365371
abstract DataFlow::Node getStringInput();
366372

367373
/**
368-
* Gets a dataflow node for the options input that might contain parse mode
374+
* Gets a dataflow node for an options input that might contain parse mode
369375
* flags (if any).
370376
*/
371377
DataFlow::Node getAnOptionsInput() { none() }

swift/ql/lib/codeql/swift/regex/internal/RegexTracking.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ private module StringLiteralUseConfig implements DataFlow::ConfigSig {
2020

2121
predicate isSink(DataFlow::Node node) {
2222
// evaluated directly as a regular expression
23-
node = any(PotentialRegexEval eval).getRegexInput()
23+
node.asExpr() = any(RegexEval eval).getRegexInput()
2424
or
2525
// used to create a regular expression object
2626
node = any(RegexCreation regexCreation).getStringInput()
@@ -41,7 +41,7 @@ private module RegexUseConfig implements DataFlow::ConfigSig {
4141

4242
predicate isSink(DataFlow::Node node) {
4343
// evaluation of the regex
44-
node = any(PotentialRegexEval eval).getRegexInput()
44+
node.asExpr() = any(RegexEval eval).getRegexInput()
4545
}
4646

4747
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
@@ -67,8 +67,8 @@ private module RegexParseModeConfig implements DataFlow::StateConfigSig {
6767
predicate isSink(DataFlow::Node node, FlowState flowstate) {
6868
// evaluation of a regex
6969
(
70-
node = any(PotentialRegexEval eval).getRegexInput() or
71-
node = any(PotentialRegexEval eval).getAnOptionsInput()
70+
node.asExpr() = any(RegexEval eval).getRegexInput() or
71+
node = any(RegexEval eval).getAnOptionsInput()
7272
) and
7373
exists(flowstate)
7474
}

swift/ql/test/library-tests/regex/parse.expected

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6334,21 +6334,11 @@ regex.swift:
63346334
# 129| [RegExpStar] .*
63356335
#-----| 0 -> [RegExpDot] .
63366336

6337-
# 130| [RegExpDot] .
6338-
6339-
# 130| [RegExpStar] .*
6340-
#-----| 0 -> [RegExpDot] .
6341-
63426337
# 131| [RegExpDot] .
63436338

63446339
# 131| [RegExpStar] .*
63456340
#-----| 0 -> [RegExpDot] .
63466341

6347-
# 132| [RegExpDot] .
6348-
6349-
# 132| [RegExpStar] .*
6350-
#-----| 0 -> [RegExpDot] .
6351-
63526342
# 136| [RegExpDot] .
63536343

63546344
# 136| [RegExpStar] .*
@@ -6374,21 +6364,11 @@ regex.swift:
63746364
# 153| [RegExpStar] .*
63756365
#-----| 0 -> [RegExpDot] .
63766366

6377-
# 154| [RegExpDot] .
6378-
6379-
# 154| [RegExpStar] .*
6380-
#-----| 0 -> [RegExpDot] .
6381-
63826367
# 155| [RegExpDot] .
63836368

63846369
# 155| [RegExpStar] .*
63856370
#-----| 0 -> [RegExpDot] .
63866371

6387-
# 156| [RegExpDot] .
6388-
6389-
# 156| [RegExpStar] .*
6390-
#-----| 0 -> [RegExpDot] .
6391-
63926372
# 160| [RegExpDot] .
63936373

63946374
# 160| [RegExpStar] .*

swift/ql/test/library-tests/regex/regex.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ func myRegexpMethodsTests(b: Bool, str_unknown: String) throws {
127127
// --- StringProtocol ---
128128

129129
_ = input.range(of: ".*", options: .regularExpression, range: nil, locale: nil) // $ regex=.* input=input
130-
_ = input.range(of: ".*", options: .literal, range: nil, locale: nil) // $ SPURIOUS: unevaluated-regex=.* (not a regular expression)
130+
_ = input.range(of: ".*", options: .literal, range: nil, locale: nil) // (not a regular expression)
131131
_ = input.replacingOccurrences(of: ".*", with: "", options: .regularExpression) // $ regex=.* input=input
132-
_ = input.replacingOccurrences(of: ".*", with: "", options: .literal) // $ SPURIOUS: unevaluated-regex=.* (not a regular expression)
132+
_ = input.replacingOccurrences(of: ".*", with: "", options: .literal) // (not a regular expression)
133133

134134
// --- NSRegularExpression ---
135135

@@ -151,9 +151,9 @@ func myRegexpMethodsTests(b: Bool, str_unknown: String) throws {
151151
_ = inputNS.range(of: ".*", options: [.regularExpression]) // $ regex=.* input=inputNS
152152
_ = inputNS.range(of: ".*", options: regexOptions) // $ regex=.* input=inputNS
153153
_ = inputNS.range(of: ".*", options: regexOptions2) // $ regex=.* input=inputNS modes=IGNORECASE
154-
_ = inputNS.range(of: ".*", options: .literal) // $ SPURIOUS: unevaluated-regex=.* (not a regular expression)
154+
_ = inputNS.range(of: ".*", options: .literal) // (not a regular expression)
155155
_ = inputNS.replacingOccurrences(of: ".*", with: "", options: .regularExpression, range: NSMakeRange(0, inputNS.length)) // $ regex=.* input=inputNS
156-
_ = inputNS.replacingOccurrences(of: ".*", with: "", options: .literal, range: NSMakeRange(0, inputNS.length)) // $ SPURIOUS: unevaluated-regex=.* (not a regular expression)
156+
_ = inputNS.replacingOccurrences(of: ".*", with: "", options: .literal, range: NSMakeRange(0, inputNS.length)) // (not a regular expression)
157157

158158
// --- flow ---
159159

0 commit comments

Comments
 (0)