Skip to content

Commit e86ccf8

Browse files
committed
Swift: Test flow through various conversions.
1 parent a1234d4 commit e86ccf8

File tree

3 files changed

+217
-0
lines changed

3 files changed

+217
-0
lines changed

swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,82 @@
1+
| conversions.swift:9:7:9:7 | SSA def(self) | conversions.swift:9:7:9:7 | self[return] |
2+
| conversions.swift:9:7:9:7 | SSA def(self) | conversions.swift:9:7:9:7 | self[return] |
3+
| conversions.swift:9:7:9:7 | self | conversions.swift:9:7:9:7 | SSA def(self) |
4+
| conversions.swift:9:7:9:7 | self | conversions.swift:9:7:9:7 | SSA def(self) |
5+
| conversions.swift:12:7:12:7 | SSA def(self) | conversions.swift:12:7:12:7 | self[return] |
6+
| conversions.swift:12:7:12:7 | self | conversions.swift:12:7:12:7 | SSA def(self) |
7+
| conversions.swift:12:36:12:36 | SSA def(self) | conversions.swift:12:36:12:36 | self[return] |
8+
| conversions.swift:12:36:12:36 | self | conversions.swift:12:36:12:36 | SSA def(self) |
9+
| conversions.swift:15:7:15:7 | SSA def(self) | conversions.swift:15:7:15:7 | self[return] |
10+
| conversions.swift:15:7:15:7 | self | conversions.swift:15:7:15:7 | SSA def(self) |
11+
| conversions.swift:16:11:16:11 | SSA def(self) | conversions.swift:16:11:16:42 | self[return] |
12+
| conversions.swift:16:11:16:11 | self | conversions.swift:16:11:16:11 | SSA def(self) |
13+
| conversions.swift:18:28:18:28 | SSA def(self) | conversions.swift:18:28:18:44 | self[return] |
14+
| conversions.swift:18:28:18:28 | self | conversions.swift:18:28:18:28 | SSA def(self) |
15+
| conversions.swift:19:33:19:33 | SSA def(self) | conversions.swift:19:33:19:49 | self[return] |
16+
| conversions.swift:19:33:19:33 | self | conversions.swift:19:33:19:33 | SSA def(self) |
17+
| conversions.swift:20:22:20:22 | SSA def(self) | conversions.swift:20:22:20:38 | self[return] |
18+
| conversions.swift:20:22:20:22 | self | conversions.swift:20:22:20:22 | SSA def(self) |
19+
| conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) |
20+
| conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 |
21+
| conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) |
22+
| conversions.swift:30:20:30:33 | call to sourceString() | conversions.swift:30:20:30:35 | .utf8 |
23+
| conversions.swift:32:9:32:9 | SSA def(v) | conversions.swift:33:13:33:13 | v |
24+
| conversions.swift:32:9:32:9 | v | conversions.swift:32:9:32:9 | SSA def(v) |
25+
| conversions.swift:32:13:32:23 | call to sourceInt() | conversions.swift:32:5:32:9 | let ...? |
26+
| conversions.swift:36:6:36:6 | SSA def(v2) | conversions.swift:37:12:37:12 | v2 |
27+
| conversions.swift:36:6:36:6 | v2 | conversions.swift:36:6:36:6 | SSA def(v2) |
28+
| conversions.swift:36:6:36:10 | ... as ... | conversions.swift:36:6:36:6 | v2 |
29+
| conversions.swift:36:18:36:41 | call to numericCast(_:) | conversions.swift:36:6:36:10 | ... as ... |
30+
| conversions.swift:39:6:39:6 | SSA def(v4) | conversions.swift:40:12:40:12 | v4 |
31+
| conversions.swift:39:6:39:6 | v4 | conversions.swift:39:6:39:6 | SSA def(v4) |
32+
| conversions.swift:39:6:39:10 | ... as ... | conversions.swift:39:6:39:6 | v4 |
33+
| conversions.swift:39:17:39:57 | call to unsafeBitCast(_:to:) | conversions.swift:39:6:39:10 | ... as ... |
34+
| conversions.swift:42:6:42:6 | SSA def(v5) | conversions.swift:43:12:43:12 | v5 |
35+
| conversions.swift:42:6:42:6 | v5 | conversions.swift:42:6:42:6 | SSA def(v5) |
36+
| conversions.swift:42:11:42:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:42:6:42:6 | v5 |
37+
| conversions.swift:45:6:45:6 | SSA def(v6) | conversions.swift:46:12:46:12 | v6 |
38+
| conversions.swift:45:6:45:6 | v6 | conversions.swift:45:6:45:6 | SSA def(v6) |
39+
| conversions.swift:45:11:45:39 | call to UInt.init(bitPattern:) | conversions.swift:45:6:45:6 | v6 |
40+
| conversions.swift:48:12:48:36 | call to Self.init(exactly:) | conversions.swift:48:12:48:37 | ...! |
41+
| conversions.swift:51:12:51:41 | call to Self.init(_:radix:) | conversions.swift:51:12:51:42 | ...! |
42+
| conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) |
43+
| conversions.swift:64:12:64:32 | call to String.init(_:) | conversions.swift:64:12:64:34 | .utf8 |
44+
| conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:32 | call to String.init(_:) |
45+
| conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) |
46+
| conversions.swift:80:6:80:6 | SSA def(ms1) | conversions.swift:81:12:81:12 | ms1 |
47+
| conversions.swift:80:6:80:6 | ms1 | conversions.swift:80:6:80:6 | SSA def(ms1) |
48+
| conversions.swift:80:12:80:26 | call to MyString.init(_:) | conversions.swift:80:12:80:27 | ...! |
49+
| conversions.swift:80:12:80:27 | ...! | conversions.swift:80:6:80:6 | ms1 |
50+
| conversions.swift:81:12:81:12 | [post] ms1 | conversions.swift:82:12:82:12 | ms1 |
51+
| conversions.swift:81:12:81:12 | ms1 | conversions.swift:82:12:82:12 | ms1 |
52+
| conversions.swift:82:12:82:12 | [post] ms1 | conversions.swift:83:12:83:12 | ms1 |
53+
| conversions.swift:82:12:82:12 | ms1 | conversions.swift:83:12:83:12 | ms1 |
54+
| conversions.swift:83:12:83:12 | [post] ms1 | conversions.swift:84:12:84:12 | ms1 |
55+
| conversions.swift:83:12:83:12 | ms1 | conversions.swift:84:12:84:12 | ms1 |
56+
| conversions.swift:86:6:86:6 | SSA def(ms2) | conversions.swift:87:12:87:12 | ms2 |
57+
| conversions.swift:86:6:86:6 | ms2 | conversions.swift:86:6:86:6 | SSA def(ms2) |
58+
| conversions.swift:86:12:86:35 | call to MyString.init(_:) | conversions.swift:86:12:86:36 | ...! |
59+
| conversions.swift:86:12:86:36 | ...! | conversions.swift:86:6:86:6 | ms2 |
60+
| conversions.swift:87:12:87:12 | [post] ms2 | conversions.swift:88:12:88:12 | ms2 |
61+
| conversions.swift:87:12:87:12 | ms2 | conversions.swift:88:12:88:12 | ms2 |
62+
| conversions.swift:88:12:88:12 | [post] ms2 | conversions.swift:89:12:89:12 | ms2 |
63+
| conversions.swift:88:12:88:12 | ms2 | conversions.swift:89:12:89:12 | ms2 |
64+
| conversions.swift:89:12:89:12 | [post] ms2 | conversions.swift:90:12:90:12 | ms2 |
65+
| conversions.swift:89:12:89:12 | ms2 | conversions.swift:90:12:90:12 | ms2 |
66+
| conversions.swift:94:6:94:6 | SSA def(parent) | conversions.swift:95:12:95:12 | parent |
67+
| conversions.swift:94:6:94:6 | parent | conversions.swift:94:6:94:6 | SSA def(parent) |
68+
| conversions.swift:94:6:94:15 | ... as ... | conversions.swift:94:6:94:6 | parent |
69+
| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:94:6:94:15 | ... as ... |
70+
| conversions.swift:95:12:95:12 | [post] parent | conversions.swift:96:12:96:12 | parent |
71+
| conversions.swift:95:12:95:12 | parent | conversions.swift:96:12:96:12 | parent |
72+
| conversions.swift:96:12:96:12 | [post] parent | conversions.swift:98:40:98:40 | parent |
73+
| conversions.swift:96:12:96:12 | parent | conversions.swift:98:40:98:40 | parent |
74+
| conversions.swift:98:6:98:6 | SSA def(v3) | conversions.swift:99:12:99:12 | v3 |
75+
| conversions.swift:98:6:98:6 | v3 | conversions.swift:98:6:98:6 | SSA def(v3) |
76+
| conversions.swift:98:6:98:10 | ... as ... | conversions.swift:98:6:98:6 | v3 |
77+
| conversions.swift:98:25:98:69 | call to unsafeDowncast(_:to:) | conversions.swift:98:6:98:10 | ... as ... |
78+
| conversions.swift:99:12:99:12 | [post] v3 | conversions.swift:100:12:100:12 | v3 |
79+
| conversions.swift:99:12:99:12 | v3 | conversions.swift:100:12:100:12 | v3 |
180
| simple.swift:12:13:12:13 | 1 | simple.swift:12:13:12:24 | ... .+(_:_:) ... |
281
| simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... |
382
| simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... |

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
edges
2+
| conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) |
3+
| conversions.swift:29:12:29:30 | call to String.init(_:) | conversions.swift:29:12:29:32 | .utf8 |
4+
| conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:30 | call to String.init(_:) |
5+
| conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) |
6+
| conversions.swift:64:12:64:32 | call to String.init(_:) | conversions.swift:64:12:64:34 | .utf8 |
7+
| conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:32 | call to String.init(_:) |
8+
| conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) |
9+
| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent |
10+
| conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent |
211
| file://:0:0:0:0 | self [first] | file://:0:0:0:0 | .first |
312
| file://:0:0:0:0 | self [second] | file://:0:0:0:0 | .second |
413
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [first] |
@@ -77,6 +86,24 @@ edges
7786
| try.swift:18:18:18:25 | call to source() | try.swift:18:18:18:25 | call to source() [some:0] |
7887
| try.swift:18:18:18:25 | call to source() [some:0] | try.swift:18:13:18:25 | try? ... [some:0] |
7988
nodes
89+
| conversions.swift:24:12:24:22 | call to sourceInt() | semmle.label | call to sourceInt() |
90+
| conversions.swift:28:12:28:30 | call to String.init(_:) | semmle.label | call to String.init(_:) |
91+
| conversions.swift:28:19:28:29 | call to sourceInt() | semmle.label | call to sourceInt() |
92+
| conversions.swift:29:12:29:30 | call to String.init(_:) | semmle.label | call to String.init(_:) |
93+
| conversions.swift:29:12:29:32 | .utf8 | semmle.label | .utf8 |
94+
| conversions.swift:29:19:29:29 | call to sourceInt() | semmle.label | call to sourceInt() |
95+
| conversions.swift:60:12:60:24 | call to sourceFloat() | semmle.label | call to sourceFloat() |
96+
| conversions.swift:63:12:63:32 | call to String.init(_:) | semmle.label | call to String.init(_:) |
97+
| conversions.swift:63:19:63:31 | call to sourceFloat() | semmle.label | call to sourceFloat() |
98+
| conversions.swift:64:12:64:32 | call to String.init(_:) | semmle.label | call to String.init(_:) |
99+
| conversions.swift:64:12:64:34 | .utf8 | semmle.label | .utf8 |
100+
| conversions.swift:64:19:64:31 | call to sourceFloat() | semmle.label | call to sourceFloat() |
101+
| conversions.swift:77:12:77:25 | call to sourceString() | semmle.label | call to sourceString() |
102+
| conversions.swift:78:12:78:33 | call to String.init(_:) | semmle.label | call to String.init(_:) |
103+
| conversions.swift:78:19:78:32 | call to sourceString() | semmle.label | call to sourceString() |
104+
| conversions.swift:94:31:94:44 | call to sourceString() | semmle.label | call to sourceString() |
105+
| conversions.swift:95:12:95:12 | parent | semmle.label | parent |
106+
| conversions.swift:96:12:96:12 | parent | semmle.label | parent |
80107
| file://:0:0:0:0 | .first | semmle.label | .first |
81108
| file://:0:0:0:0 | .second | semmle.label | .second |
82109
| file://:0:0:0:0 | [post] self [first] | semmle.label | [post] self [first] |
@@ -200,6 +227,16 @@ subpaths
200227
| stringinterpolation.swift:28:14:28:21 | call to source() | stringinterpolation.swift:7:6:7:6 | value | file://:0:0:0:0 | [post] self [second] | stringinterpolation.swift:28:2:28:2 | [post] p2 [second] |
201228
| stringinterpolation.swift:31:21:31:21 | p2 [second] | stringinterpolation.swift:7:6:7:6 | self [second] | file://:0:0:0:0 | .second | stringinterpolation.swift:31:21:31:24 | .second |
202229
#select
230+
| conversions.swift:24:12:24:22 | call to sourceInt() | conversions.swift:24:12:24:22 | call to sourceInt() | conversions.swift:24:12:24:22 | call to sourceInt() | result |
231+
| conversions.swift:28:12:28:30 | call to String.init(_:) | conversions.swift:28:19:28:29 | call to sourceInt() | conversions.swift:28:12:28:30 | call to String.init(_:) | result |
232+
| conversions.swift:29:12:29:32 | .utf8 | conversions.swift:29:19:29:29 | call to sourceInt() | conversions.swift:29:12:29:32 | .utf8 | result |
233+
| conversions.swift:60:12:60:24 | call to sourceFloat() | conversions.swift:60:12:60:24 | call to sourceFloat() | conversions.swift:60:12:60:24 | call to sourceFloat() | result |
234+
| conversions.swift:63:12:63:32 | call to String.init(_:) | conversions.swift:63:19:63:31 | call to sourceFloat() | conversions.swift:63:12:63:32 | call to String.init(_:) | result |
235+
| conversions.swift:64:12:64:34 | .utf8 | conversions.swift:64:19:64:31 | call to sourceFloat() | conversions.swift:64:12:64:34 | .utf8 | result |
236+
| conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | conversions.swift:77:12:77:25 | call to sourceString() | result |
237+
| conversions.swift:78:12:78:33 | call to String.init(_:) | conversions.swift:78:19:78:32 | call to sourceString() | conversions.swift:78:12:78:33 | call to String.init(_:) | result |
238+
| conversions.swift:95:12:95:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:95:12:95:12 | parent | result |
239+
| conversions.swift:96:12:96:12 | parent | conversions.swift:94:31:94:44 | call to sourceString() | conversions.swift:96:12:96:12 | parent | result |
203240
| simple.swift:12:13:12:24 | ... .+(_:_:) ... | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | result |
204241
| simple.swift:13:13:13:24 | ... .+(_:_:) ... | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | result |
205242
| simple.swift:14:13:14:24 | ... .-(_:_:) ... | simple.swift:14:17:14:24 | call to source() | simple.swift:14:13:14:24 | ... .-(_:_:) ... | result |
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
2+
func sourceInt() -> Int { 0 }
3+
func sourceFloat() -> Float { 0.0 }
4+
func sourceString() -> String { "" }
5+
func sink(arg: Any) { }
6+
7+
// ---
8+
9+
class MyParentClass {
10+
}
11+
12+
class MyChildClass : MyParentClass {
13+
}
14+
15+
class MyString : LosslessStringConvertible, CustomStringConvertible, CustomDebugStringConvertible {
16+
required init?(_ description: String) { }
17+
18+
var description: String { get { return "" } }
19+
var debugDescription: String { get { return "" } }
20+
var clean: String { get { return "" } }
21+
}
22+
23+
func testConversions() {
24+
sink(arg: sourceInt()) // $ tainted=24
25+
sink(arg: Int(sourceInt())) // $ MISSING: tainted=
26+
sink(arg: UInt8(sourceInt())) // $ MISSING: tainted=
27+
sink(arg: Float(sourceInt())) // $ MISSING: tainted=
28+
sink(arg: String(sourceInt())) // $ tainted=28
29+
sink(arg: String(sourceInt()).utf8) // $ tainted=29
30+
sink(arg: [UInt8](sourceString().utf8)) // $ MISSING: tainted=
31+
32+
if let v = sourceInt() as? UInt {
33+
sink(arg: v) // $ MISSING: tainted=
34+
}
35+
36+
let v2: UInt8 = numericCast(sourceInt())
37+
sink(arg: v2) // $ MISSING: tainted=
38+
39+
let v4: UInt = unsafeBitCast(sourceInt(), to: UInt.self)
40+
sink(arg: v4) // $ MISSING: tainted=
41+
42+
let v5 = UInt(truncatingIfNeeded: sourceInt())
43+
sink(arg: v5) // $ MISSING: tainted=
44+
45+
let v6 = UInt(bitPattern: sourceInt())
46+
sink(arg: v6) // $ MISSING: tainted=
47+
48+
sink(arg: Int(exactly: sourceInt())!) // $ MISSING: tainted=
49+
sink(arg: Int(clamping: sourceInt())) // $ MISSING: tainted=
50+
sink(arg: Int(truncatingIfNeeded: sourceInt())) // $ MISSING: tainted=
51+
sink(arg: Int(sourceString(), radix: 10)!) // $ MISSING: tainted=
52+
53+
sink(arg: Int(littleEndian: sourceInt())) // $ MISSING: tainted=
54+
sink(arg: Int(bigEndian: sourceInt())) // $ MISSING: tainted=
55+
sink(arg: sourceInt().littleEndian) // $ MISSING: tainted=
56+
sink(arg: sourceInt().bigEndian) // $ MISSING: tainted=
57+
58+
// ---
59+
60+
sink(arg: sourceFloat()) // $ tainted=60
61+
sink(arg: Float(sourceFloat())) // $ MISSING: tainted=
62+
sink(arg: UInt8(sourceFloat())) // $ MISSING: tainted=
63+
sink(arg: String(sourceFloat())) // $ tainted=63
64+
sink(arg: String(sourceFloat()).utf8) // $ tainted=64
65+
66+
sink(arg: Float(sourceFloat())) // MISSING: tainted=
67+
sink(arg: Float(sign: .plus, exponent: sourceInt(), significand: 0.0)) // MISSING: tainted=
68+
sink(arg: Float(sign: .plus, exponent: 0, significand: sourceFloat())) // MISSING: tainted=
69+
sink(arg: Float(signOf: sourceFloat(), magnitudeOf: 0.0)) // (good)
70+
sink(arg: Float(signOf: 0.0, magnitudeOf: sourceFloat())) // MISSING: tainted=
71+
72+
sink(arg: sourceFloat().exponent) // $ MISSING: tainted=
73+
sink(arg: sourceFloat().significand) // $ MISSING: tainted=
74+
75+
// ---
76+
77+
sink(arg: sourceString()) // $ tainted=77
78+
sink(arg: String(sourceString())) // $ tainted=78
79+
80+
let ms1 = MyString("abc")!
81+
sink(arg: ms1)
82+
sink(arg: ms1.description)
83+
sink(arg: ms1.debugDescription)
84+
sink(arg: ms1.clean)
85+
86+
let ms2 = MyString(sourceString())!
87+
sink(arg: ms2) // $ MISSING: tainted=
88+
sink(arg: ms2.description) // $ MISSING: tainted=
89+
sink(arg: ms2.debugDescription) // $ MISSING: tainted=
90+
sink(arg: ms2.clean)
91+
92+
// ---
93+
94+
let parent : MyParentClass = sourceString() as! MyChildClass
95+
sink(arg: parent) // $ tainted=94
96+
sink(arg: parent as! MyChildClass) // $ tainted=94
97+
98+
let v3: MyChildClass = unsafeDowncast(parent, to: MyChildClass.self)
99+
sink(arg: v3) // $ MISSING: tainted=
100+
sink(arg: v3 as! MyParentClass) // $ MISSING: tainted=
101+
}

0 commit comments

Comments
 (0)