Skip to content

Commit

Permalink
Swift: Change method types to DataFlow::Node / go ahead with planned …
Browse files Browse the repository at this point in the history
…deprecations.
  • Loading branch information
geoffw0 committed Oct 25, 2023
1 parent bfd150a commit 82b92c3
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 18 deletions.
37 changes: 23 additions & 14 deletions swift/ql/lib/codeql/swift/regex/Regex.qll
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ abstract class RegexCreation extends DataFlow::Node {
abstract DataFlow::Node getStringInput();

/**
* Gets a dataflow node for an options input that might contain parse mode
* flags (if any).
* Gets a dataflow node for an options input that might contain options
* such as parse mode flags (if any).
*/
DataFlow::Node getAnOptionsInput() { none() }

Expand Down Expand Up @@ -307,16 +307,26 @@ abstract class RegexEval extends CallExpr {
* Consider using `getARegex()` instead (which tracks the regular expression
* input back to its source).
*/
abstract Expr getRegexInput();
abstract DataFlow::Node getRegexInputNode();

/**
* DEPRECATED: Use `getRegexInputNode()` instead.
*/
deprecated Expr getRegexInput() { result = this.getRegexInputNode().asExpr() }

/**
* Gets the input to this call that is the string the regular expression is evaluated on.
*/
abstract Expr getStringInput();
abstract DataFlow::Node getStringInputNode();

/**
* DEPRECATED: Use `getStringInputNode()` instead.
*/
deprecated Expr getStringInput() { result = this.getStringInputNode().asExpr() }

/**
* Gets a dataflow node for an options input that might contain parse mode
* flags (if any).
* Gets a dataflow node for an options input that might contain options such
* as parse mode flags (if any).
*/
DataFlow::Node getAnOptionsInput() { none() }

Expand All @@ -325,13 +335,12 @@ abstract class RegexEval extends CallExpr {
*/
RegExp getARegex() {
// string literal used directly as a regex
DataFlow::exprNode(result).(ParsedStringRegex).getAParse() =
DataFlow::exprNode(this.getRegexInput())
DataFlow::exprNode(result).(ParsedStringRegex).getAParse() = this.getRegexInputNode()
or
// string literal -> regex object -> use
exists(RegexCreation regexCreation |
DataFlow::exprNode(result).(ParsedStringRegex).getAParse() = regexCreation.getStringInput() and
RegexUseFlow::flow(regexCreation, DataFlow::exprNode(this.getRegexInput()))
RegexUseFlow::flow(regexCreation, this.getRegexInputNode())
)
}

Expand All @@ -345,7 +354,7 @@ abstract class RegexEval extends CallExpr {
any(RegexAdditionalFlowStep s).setsParseMode(setNode, result, true) and
// reaches this eval
(
RegexParseModeFlow::flow(setNode, DataFlow::exprNode(this.getRegexInput())) or
RegexParseModeFlow::flow(setNode, this.getRegexInputNode()) or
RegexParseModeFlow::flow(setNode, this.getAnOptionsInput())
)
)
Expand Down Expand Up @@ -404,9 +413,9 @@ private class AlwaysRegexEval extends RegexEval {
stringInput.asExpr() = this.getQualifier()
}

override Expr getRegexInput() { result = regexInput.asExpr() }
override DataFlow::Node getRegexInputNode() { result = regexInput }

override Expr getStringInput() { result = stringInput.asExpr() }
override DataFlow::Node getStringInputNode() { result = stringInput }
}

/**
Expand Down Expand Up @@ -489,9 +498,9 @@ private class NSStringCompareOptionsRegexEval extends RegexEval {
NSStringCompareOptionsFlagFlow::flow(_, potentialEval.getAnOptionsInput())
}

override Expr getRegexInput() { result = potentialEval.getRegexInput().asExpr() }
override DataFlow::Node getRegexInputNode() { result = potentialEval.getRegexInput() }

override Expr getStringInput() { result = potentialEval.getStringInput().asExpr() }
override DataFlow::Node getStringInputNode() { result = potentialEval.getStringInput() }

override DataFlow::Node getAnOptionsInput() { result = potentialEval.getAnOptionsInput() }
}
6 changes: 3 additions & 3 deletions swift/ql/lib/codeql/swift/regex/internal/RegexTracking.qll
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ private module StringLiteralUseConfig implements DataFlow::ConfigSig {

predicate isSink(DataFlow::Node node) {
// evaluated directly as a regular expression
node.asExpr() = any(RegexEval eval).getRegexInput()
node = any(RegexEval eval).getRegexInputNode()
or
// used to create a regular expression object
node = any(RegexCreation regexCreation).getStringInput()
Expand All @@ -41,7 +41,7 @@ private module RegexUseConfig implements DataFlow::ConfigSig {

predicate isSink(DataFlow::Node node) {
// evaluation of the regex
node.asExpr() = any(RegexEval eval).getRegexInput()
node = any(RegexEval eval).getRegexInputNode()
}

predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
Expand All @@ -67,7 +67,7 @@ private module RegexParseModeConfig implements DataFlow::StateConfigSig {
predicate isSink(DataFlow::Node node, FlowState flowstate) {
// evaluation of a regex
(
node.asExpr() = any(RegexEval eval).getRegexInput() or
node = any(RegexEval eval).getRegexInputNode() or
node = any(RegexEval eval).getAnOptionsInput()
) and
exists(flowstate)
Expand Down
2 changes: 1 addition & 1 deletion swift/ql/test/library-tests/regex/regex.ql
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ module RegexTest implements TestSig {

predicate hasOptionalResult(Location location, string element, string tag, string value) {
exists(RegexEval eval, Expr input |
eval.getStringInput() = input and
eval.getStringInputNode().asExpr() = input and
location = input.getLocation() and
element = input.toString() and
tag = "input" and
Expand Down

0 comments on commit 82b92c3

Please sign in to comment.