Skip to content

Commit 2ee1979

Browse files
authored
Merge pull request #10014 from geoffw0/inlinetaint
Swift: Add an inline expectations test for taint flow
2 parents ff23f8e + 1dcc44f commit 2ee1979

File tree

8 files changed

+71
-49
lines changed

8 files changed

+71
-49
lines changed

swift/ql/test/library-tests/dataflow/taint/Taint.ql

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,9 @@
33
*/
44

55
import swift
6-
import codeql.swift.dataflow.TaintTracking
7-
import codeql.swift.dataflow.DataFlow::DataFlow
6+
import Taint
87
import PathGraph
98

10-
class TestConfiguration extends TaintTracking::Configuration {
11-
TestConfiguration() { this = "TestConfiguration" }
12-
13-
override predicate isSource(Node src) {
14-
src.asExpr().(CallExpr).getStaticTarget().getName().matches("source%")
15-
}
16-
17-
override predicate isSink(Node sink) {
18-
exists(CallExpr sinkCall |
19-
sinkCall.getStaticTarget().getName().matches("sink%") and
20-
sinkCall.getAnArgument().getExpr() = sink.asExpr()
21-
)
22-
}
23-
24-
override int explorationLimit() { result = 100 }
25-
}
26-
279
from PathNode src, PathNode sink, TestConfiguration test
2810
where test.hasFlowPath(src, sink)
2911
select sink, src, sink, "result"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import swift
2+
import codeql.swift.dataflow.TaintTracking
3+
import codeql.swift.dataflow.DataFlow::DataFlow
4+
5+
class TestConfiguration extends TaintTracking::Configuration {
6+
TestConfiguration() { this = "TestConfiguration" }
7+
8+
override predicate isSource(Node src) {
9+
src.asExpr().(CallExpr).getStaticTarget().getName().matches("source%")
10+
}
11+
12+
override predicate isSink(Node sink) {
13+
exists(CallExpr sinkCall |
14+
sinkCall.getStaticTarget().getName().matches("sink%") and
15+
sinkCall.getAnArgument().getExpr() = sink.asExpr()
16+
)
17+
}
18+
19+
override int explorationLimit() { result = 100 }
20+
}

swift/ql/test/library-tests/dataflow/taint/TaintInline.expected

Whitespace-only changes.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import swift
2+
import Taint
3+
import TestUtilities.InlineExpectationsTest
4+
5+
class TaintTest extends InlineExpectationsTest {
6+
TaintTest() { this = "TaintTest" }
7+
8+
override string getARelevantTag() { result = "tainted" }
9+
10+
override predicate hasActualResult(Location location, string element, string tag, string value) {
11+
exists(TestConfiguration config, Node source, Node sink, Expr sinkExpr |
12+
config.hasFlow(source, sink) and
13+
sinkExpr = sink.asExpr() and
14+
location = sinkExpr.getLocation() and
15+
element = sinkExpr.toString() and
16+
tag = "tainted" and
17+
value = source.asExpr().getLocation().getStartLine().toString()
18+
)
19+
}
20+
}

swift/ql/test/library-tests/dataflow/taint/data.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ func taintThroughData() {
1414
let dataTainted2 = Data(dataTainted)
1515

1616
sink(arg: dataClean)
17-
sink(arg: dataTainted) // tainted [NOT DETECTED]
18-
sink(arg: dataTainted2) // tainted [NOT DETECTED]
17+
sink(arg: dataTainted) // $ MISSING: tainted=13
18+
sink(arg: dataTainted2) // $ MISSING: tainted=13
1919

2020
let stringClean = String(data: dataClean, encoding: String.Encoding.utf8)
2121
let stringTainted = String(data: dataTainted, encoding: String.Encoding.utf8)
2222

23-
sink2(arg: stringClean!) // tainted [NOT DETECTED]
24-
sink2(arg: stringTainted!) // tainted [NOT DETECTED]
23+
sink2(arg: stringClean!) // $ MISSING: tainted=13
24+
sink2(arg: stringTainted!) // $ MISSING: tainted=13
2525
}

swift/ql/test/library-tests/dataflow/taint/string.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ func sink(arg: String) {}
44
func taintThroughInterpolatedStrings() {
55
var x = source()
66

7-
sink(arg: "\(x)") // tainted
7+
sink(arg: "\(x)") // $ tainted=5
88

9-
sink(arg: "\(x) \(x)") // tainted
9+
sink(arg: "\(x) \(x)") // $ tainted=5
1010

11-
sink(arg: "\(x) \(0) \(x)") // tainted
11+
sink(arg: "\(x) \(0) \(x)") // $ tainted=5
1212

1313
var y = 42
1414
sink(arg: "\(y)") // clean
1515

16-
sink(arg: "\(x) hello \(y)") // tainted
16+
sink(arg: "\(x) hello \(y)") // $ tainted=5
1717

18-
sink(arg: "\(y) world \(x)") // tainted
18+
sink(arg: "\(y) world \(x)") // $ tainted=5
1919

2020
x = 0
2121
sink(arg: "\(x)") // clean
@@ -28,15 +28,15 @@ func taintThroughStringConcatenation() {
2828
var tainted = source2()
2929

3030
sink(arg: clean)
31-
sink(arg: tainted) // tainted
31+
sink(arg: tainted) // $ tainted=28
3232

3333
sink(arg: clean + clean)
34-
sink(arg: clean + tainted) // tainted
35-
sink(arg: tainted + clean) // tainted
36-
sink(arg: tainted + tainted) // tainted
34+
sink(arg: clean + tainted) // $ tainted=28
35+
sink(arg: tainted + clean) // $ tainted=28
36+
sink(arg: tainted + tainted) // $ tainted=28
3737

3838
sink(arg: ">" + clean + "<")
39-
sink(arg: ">" + tainted + "<") // tainted
39+
sink(arg: ">" + tainted + "<") // $ tainted=28
4040

4141
var str = "abc"
4242

@@ -46,7 +46,7 @@ func taintThroughStringConcatenation() {
4646
sink(arg: str)
4747

4848
str += source2()
49-
sink(arg: str) // tainted [NOT DETECTED]
49+
sink(arg: str) // $ MISSING: tainted=48
5050

5151
var str2 = "abc"
5252

@@ -56,7 +56,7 @@ func taintThroughStringConcatenation() {
5656
sink(arg: str2)
5757

5858
str2.append(source2())
59-
sink(arg: str2) // tainted [NOT DETECTED]
59+
sink(arg: str2) // $ MISSING: tainted=58
6060

6161
var str3 = "abc"
6262

@@ -66,7 +66,7 @@ func taintThroughStringConcatenation() {
6666
sink(arg: str3)
6767

6868
str3.append(contentsOf: source2())
69-
sink(arg: str2) // tainted [NOT DETECTED]
69+
sink(arg: str2) // $ MISSING: tainted=68
7070
}
7171

7272
func taintThroughStringOperations() {
@@ -75,15 +75,15 @@ func taintThroughStringOperations() {
7575
var taintedInt = source()
7676

7777
sink(arg: String(clean))
78-
sink(arg: String(tainted)) // tainted [NOT DETECTED]
79-
sink(arg: String(taintedInt)) // tainted [NOT DETECTED]
78+
sink(arg: String(tainted)) // $ MISSING: tainted=74
79+
sink(arg: String(taintedInt)) // $ MISSING: tainted=75
8080

8181
sink(arg: String(repeating: clean, count: 2))
82-
sink(arg: String(repeating: tainted, count: 2)) // tainted [NOT DETECTED]
82+
sink(arg: String(repeating: tainted, count: 2)) // $ MISSING: tainted=74
8383

8484
sink(arg: clean.description)
85-
sink(arg: tainted.description) // tainted [NOT DETECTED]
85+
sink(arg: tainted.description) // $ MISSING: tainted=74
8686

8787
sink(arg: clean.debugDescription)
88-
sink(arg: tainted.debugDescription) // tainted [NOT DETECTED]
88+
sink(arg: tainted.debugDescription) // $ MISSING: tainted=74
8989
}

swift/ql/test/library-tests/dataflow/taint/try.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ func taintThroughTry() {
66
do
77
{
88
sink(arg: try clean())
9-
sink(arg: try source()) // tainted
9+
sink(arg: try source()) // $ tainted=9
1010
} catch {
1111
// ...
1212
}
1313

1414
sink(arg: try! clean())
15-
sink(arg: try! source()) // tainted
15+
sink(arg: try! source()) // $ tainted=15
1616

1717
sink(arg: (try? clean())!)
18-
sink(arg: (try? source())!) // tainted
18+
sink(arg: (try? source())!) // $ tainted=18
1919
}

swift/ql/test/library-tests/dataflow/taint/url.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ func taintThroughURL() {
1515
let urlTainted = URL(string: tainted)!
1616

1717
sink(arg: urlClean)
18-
sink(arg: urlTainted) // tainted
18+
sink(arg: urlTainted) // $ tainted=13
1919

2020
sink(arg: URL(string: clean, relativeTo: nil)!)
21-
sink(arg: URL(string: tainted, relativeTo: nil)!) // tainted
21+
sink(arg: URL(string: tainted, relativeTo: nil)!) // $ tainted=13
2222
sink(arg: URL(string: clean, relativeTo: urlClean)!)
23-
sink(arg: URL(string: clean, relativeTo: urlTainted)!) // tainted
23+
sink(arg: URL(string: clean, relativeTo: urlTainted)!) // $ tainted=13
2424

2525
if let x = URL(string: clean) {
2626
sink(arg: x)
2727
}
2828

2929
if let y = URL(string: tainted) {
30-
sink(arg: y) // tainted [NOT DETECTED]
30+
sink(arg: y) // $ MISSING: tainted=13
3131
}
3232

3333
var urlClean2 : URL!
@@ -36,5 +36,5 @@ func taintThroughURL() {
3636

3737
var urlTainted2 : URL!
3838
urlTainted2 = URL(string: tainted)
39-
sink(arg: urlTainted2) // tainted
39+
sink(arg: urlTainted2) // $ tainted=13
4040
}

0 commit comments

Comments
 (0)