Skip to content

Commit fe4ef48

Browse files
committed
Swift: Rename some predicates and make them work on dataflow nodes.
1 parent b5ff104 commit fe4ef48

File tree

2 files changed

+40
-35
lines changed

2 files changed

+40
-35
lines changed

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

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,15 @@ abstract class RegexCreation extends DataFlow::Node {
6969
abstract DataFlow::Node getStringInput();
7070

7171
/**
72-
* Gets a dataflow node for the options input that might contain parse mode
72+
* Gets a dataflow node for an options input that might contain parse mode
7373
* flags (if any).
7474
*/
75-
DataFlow::Node getOptionsInput() { none() }
75+
DataFlow::Node getAnOptionsInput() { none() }
76+
77+
/**
78+
* DEPRECATED: Use `getAnOptionsInput()` instead.
79+
*/
80+
deprecated DataFlow::Node getOptionsInput() { result = this.getAnOptionsInput() }
7681
}
7782

7883
/**
@@ -110,7 +115,7 @@ private class NSRegularExpressionRegexCreation extends RegexCreation {
110115

111116
override DataFlow::Node getStringInput() { result = input }
112117

113-
override DataFlow::Node getOptionsInput() {
118+
override DataFlow::Node getAnOptionsInput() {
114119
result.asExpr() = this.asExpr().(CallExpr).getArgument(1).getExpr()
115120
}
116121
}
@@ -265,27 +270,27 @@ class NSRegularExpressionRegexAdditionalFlowStep extends RegexAdditionalFlowStep
265270
*/
266271
abstract class RegexEval extends CallExpr {
267272
/**
268-
* Gets the input to this call that is the regular expression being evaluated. This may
269-
* be a regular expression object or a string literal.
273+
* Gets the input to this call that is the regular expression being evaluated.
274+
* This may be a regular expression object or a string literal.
270275
*/
271-
abstract Expr getRegexInput();
276+
abstract DataFlow::Node getRegexInput();
272277

273278
/**
274279
* Gets the input to this call that is the string the regular expression is evaluated on.
275280
*/
276-
abstract Expr getStringInput();
281+
abstract DataFlow::Node getStringInput();
277282

278283
/**
279284
* Gets a regular expression value that is evaluated here (if any can be identified).
280285
*/
281286
RegExp getARegex() {
282287
// string literal used directly as a regex
283-
DataFlow::exprNode(result).(ParsedStringRegex).getAParse().asExpr() = this.getRegexInput()
288+
DataFlow::exprNode(result).(ParsedStringRegex).getAParse() = this.getRegexInput()
284289
or
285290
// string literal -> regex object -> use
286291
exists(RegexCreation regexCreation |
287292
DataFlow::exprNode(result).(ParsedStringRegex).getAParse() = regexCreation.getStringInput() and
288-
RegexUseFlow::flow(regexCreation, DataFlow::exprNode(this.getRegexInput()))
293+
RegexUseFlow::flow(regexCreation, this.getRegexInput())
289294
)
290295
}
291296

@@ -298,7 +303,7 @@ abstract class RegexEval extends CallExpr {
298303
// parse mode flag is set
299304
any(RegexAdditionalFlowStep s).setsParseMode(setNode, result, true) and
300305
// reaches this eval
301-
RegexParseModeFlow::flow(setNode, DataFlow::exprNode(this.getRegexInput()))
306+
RegexParseModeFlow::flow(setNode, this.getRegexInput())
302307
)
303308
}
304309
}
@@ -307,15 +312,15 @@ abstract class RegexEval extends CallExpr {
307312
* A call to a function that always evaluates a regular expression.
308313
*/
309314
private class AlwaysRegexEval extends RegexEval {
310-
Expr regexInput;
311-
Expr stringInput;
315+
DataFlow::Node regexInput;
316+
DataFlow::Node stringInput;
312317

313318
AlwaysRegexEval() {
314319
this.getStaticTarget()
315320
.(Method)
316321
.hasQualifiedName("Regex", ["firstMatch(in:)", "prefixMatch(in:)", "wholeMatch(in:)"]) and
317-
regexInput = this.getQualifier() and
318-
stringInput = this.getArgument(0).getExpr()
322+
regexInput.asExpr() = this.getQualifier() and
323+
stringInput.asExpr() = this.getArgument(0).getExpr()
319324
or
320325
this.getStaticTarget()
321326
.(Method)
@@ -327,8 +332,8 @@ private class AlwaysRegexEval extends RegexEval {
327332
"replaceMatches(in:options:range:withTemplate:)",
328333
"stringByReplacingMatches(in:options:range:withTemplate:)"
329334
]) and
330-
regexInput = this.getQualifier() and
331-
stringInput = this.getArgument(0).getExpr()
335+
regexInput.asExpr() = this.getQualifier() and
336+
stringInput.asExpr() = this.getArgument(0).getExpr()
332337
or
333338
this.getStaticTarget()
334339
.(Method)
@@ -339,8 +344,8 @@ private class AlwaysRegexEval extends RegexEval {
339344
"split(separator:maxSplits:omittingEmptySubsequences:)", "starts(with:)",
340345
"trimmingPrefix(_:)", "wholeMatch(of:)"
341346
]) and
342-
regexInput = this.getArgument(0).getExpr() and
343-
stringInput = this.getQualifier()
347+
regexInput.asExpr() = this.getArgument(0).getExpr() and
348+
stringInput.asExpr() = this.getQualifier()
344349
or
345350
this.getStaticTarget()
346351
.(Method)
@@ -351,23 +356,23 @@ private class AlwaysRegexEval extends RegexEval {
351356
"replacing(_:with:maxReplacements:)", "replacing(_:with:subrange:maxReplacements:)",
352357
"trimPrefix(_:)"
353358
]) and
354-
regexInput = this.getArgument(0).getExpr() and
355-
stringInput = this.getQualifier()
359+
regexInput.asExpr() = this.getArgument(0).getExpr() and
360+
stringInput.asExpr() = this.getQualifier()
356361
}
357362

358-
override Expr getRegexInput() { result = regexInput }
363+
override DataFlow::Node getRegexInput() { result = regexInput }
359364

360-
override Expr getStringInput() { result = stringInput }
365+
override DataFlow::Node getStringInput() { result = stringInput }
361366
}
362367

363368
/**
364369
* A call to a function that sometimes evaluates a regular expression, if
365370
* `options: .regularExpression` is set as an argument.
366371
*/
367372
private class SometimesRegexEval extends RegexEval {
368-
Expr regexInput;
369-
Expr stringInput;
370-
Expr optionsInput;
373+
DataFlow::Node regexInput;
374+
DataFlow::Node stringInput;
375+
DataFlow::Node optionsInput;
371376

372377
SometimesRegexEval() {
373378
(
@@ -384,13 +389,13 @@ private class SometimesRegexEval extends RegexEval {
384389
"replacingOccurrences(of:with:options:range:)"
385390
])
386391
) and
387-
regexInput = this.getArgument(0).getExpr() and
388-
stringInput = this.getQualifier() and
389-
optionsInput = this.getArgumentWithLabel("options").getExpr()
392+
regexInput.asExpr() = this.getArgument(0).getExpr() and
393+
stringInput.asExpr() = this.getQualifier() and
394+
optionsInput.asExpr() = this.getArgumentWithLabel("options").getExpr()
390395
// TODO: check options may have value `.regularExpression`
391396
}
392397

393-
override Expr getRegexInput() { result = regexInput }
398+
override DataFlow::Node getRegexInput() { result = regexInput }
394399

395-
override Expr getStringInput() { result = stringInput }
400+
override DataFlow::Node getStringInput() { result = stringInput }
396401
}

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

Lines changed: 5 additions & 5 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.asExpr() = any(RegexEval eval).getRegexInput()
23+
node = 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.asExpr() = any(RegexEval eval).getRegexInput()
44+
node = any(RegexEval eval).getRegexInput()
4545
}
4646

4747
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
@@ -65,8 +65,8 @@ private module RegexParseModeConfig implements DataFlow::StateConfigSig {
6565
}
6666

6767
predicate isSink(DataFlow::Node node, FlowState flowstate) {
68-
// evaluation of the regex
69-
node.asExpr() = any(RegexEval eval).getRegexInput() and
68+
// evaluation of a regex
69+
node = any(RegexEval eval).getRegexInput() and
7070
exists(flowstate)
7171
}
7272

@@ -86,7 +86,7 @@ private module RegexParseModeConfig implements DataFlow::StateConfigSig {
8686
or
8787
// flow through regex creation
8888
exists(RegexCreation create |
89-
nodeFrom = create.getOptionsInput() and
89+
nodeFrom = create.getAnOptionsInput() and
9090
nodeTo = create
9191
)
9292
or

0 commit comments

Comments
 (0)