11
22// --- stubs ---
33
4- func sourceString( ) -> String { return " " }
5- func sourceUInt8( ) -> UInt8 { return 0 }
4+ func sourceInt( _ label: String ) -> Int { return 0 }
5+ func sourceString( _ label: String ) -> String { return " " }
6+ func sourceUInt8( _ label: String ) -> UInt8 { return 0 }
67func sink( arg: Any ) { }
78
89// --- tests ---
@@ -18,14 +19,14 @@ func taintPointer(ptr: UnsafeMutablePointer<String>) {
1819 sink ( arg: ptr. pointee)
1920 sink ( arg: ptr)
2021
21- ptr. pointee = sourceString ( )
22+ ptr. pointee = sourceString ( " taintPointer " )
2223
23- sink ( arg: ptr. pointee) // $ tainted=21
24+ sink ( arg: ptr. pointee) // $ tainted=taintPointer
2425 sink ( arg: ptr)
2526}
2627
2728func clearPointer2( ptr: UnsafeMutablePointer < String > ) {
28- sink ( arg: ptr. pointee) // $ tainted=21
29+ sink ( arg: ptr. pointee) // $ tainted=taintPointer
2930 sink ( arg: ptr)
3031
3132 ptr. pointee = " abc "
@@ -42,12 +43,12 @@ func testMutatingPointerInCall(ptr: UnsafeMutablePointer<String>) {
4243
4344 taintPointer ( ptr: ptr) // mutates `ptr` pointee with a tainted value
4445
45- sink ( arg: ptr. pointee) // $ tainted=21
46+ sink ( arg: ptr. pointee) // $ tainted=taintPointer
4647 sink ( arg: ptr)
4748
4849 clearPointer2 ( ptr: ptr)
4950
50- sink ( arg: ptr. pointee) // $ SPURIOUS: tainted=21
51+ sink ( arg: ptr. pointee) // $ SPURIOUS: tainted=taintPointer
5152 sink ( arg: ptr)
5253}
5354
@@ -57,10 +58,10 @@ func taintBuffer(buffer: UnsafeMutableBufferPointer<UInt8>) {
5758 sink ( arg: buffer [ 0 ] )
5859 sink ( arg: buffer)
5960
60- buffer [ 0 ] = sourceUInt8 ( )
61+ buffer [ 0 ] = sourceUInt8 ( " taintBuffer " )
6162
62- sink ( arg: buffer [ 0 ] ) // $ tainted=60
63- sink ( arg: buffer) // $ tainted=60
63+ sink ( arg: buffer [ 0 ] ) // $ tainted=taintBuffer
64+ sink ( arg: buffer) // $ tainted=taintBuffer
6465}
6566
6667func testMutatingBufferInCall( ptr: UnsafeMutablePointer < UInt8 > ) {
@@ -71,8 +72,8 @@ func testMutatingBufferInCall(ptr: UnsafeMutablePointer<UInt8>) {
7172
7273 taintBuffer ( buffer: buffer) // mutates `buffer` contents with a tainted value
7374
74- sink ( arg: buffer [ 0 ] ) // $ tainted=60
75- sink ( arg: buffer) // $ tainted=60
75+ sink ( arg: buffer [ 0 ] ) // $ tainted=taintBuffer
76+ sink ( arg: buffer) // $ tainted=taintBuffer
7677
7778}
7879
@@ -84,9 +85,9 @@ func taintMyPointer(ptr: MyPointer) {
8485 sink ( arg: ptr. pointee)
8586 sink ( arg: ptr)
8687
87- ptr. pointee = sourceString ( )
88+ ptr. pointee = sourceString ( " taintMyPointer " )
8889
89- sink ( arg: ptr. pointee) // $ tainted=87
90+ sink ( arg: ptr. pointee) // $ tainted=taintMyPointer
9091 sink ( arg: ptr)
9192}
9293
@@ -96,7 +97,7 @@ func testMutatingMyPointerInCall(ptr: MyPointer) {
9697
9798 taintMyPointer ( ptr: ptr) // mutates `ptr` pointee with a tainted value
9899
99- sink ( arg: ptr. pointee) // $ MISSING: tainted=87
100+ sink ( arg: ptr. pointee) // $ MISSING: tainted=taintMyPointer
100101 sink ( arg: ptr)
101102}
102103
@@ -111,19 +112,94 @@ struct MyGenericPointerContainer<T> {
111112}
112113
113114func writePointerContainer( mpc: MyPointerContainer ) {
114- mpc. ptr. pointee = sourceString ( )
115- sink ( arg: mpc. ptr. pointee) // $ tainted=114
115+ mpc. ptr. pointee = sourceString ( " writePointerContainer " )
116+ sink ( arg: mpc. ptr. pointee) // $ tainted=writePointerContainer
116117}
117118
118119func writeGenericPointerContainer< T> ( mgpc: MyGenericPointerContainer < T > ) {
119- mgpc. ptr. pointee = sourceString ( ) as! T
120- sink ( arg: mgpc. ptr. pointee) // $ tainted=119
120+ mgpc. ptr. pointee = sourceString ( " writeGenericPointerContainer " ) as! T
121+ sink ( arg: mgpc. ptr. pointee) // $ tainted=writeGenericPointerContainer
121122}
122123
123124func testWritingPointerContainersInCalls( mpc: MyPointerContainer , mgpc: MyGenericPointerContainer < Int > ) {
124125 writePointerContainer ( mpc: mpc)
125- sink ( arg: mpc. ptr. pointee) // $ tainted=114
126+ sink ( arg: mpc. ptr. pointee) // $ tainted=writePointerContainer
126127
127128 writeGenericPointerContainer ( mgpc: mgpc)
128- sink ( arg: mgpc. ptr. pointee) // $ tainted=119
129+ sink ( arg: mgpc. ptr. pointee) // $ tainted=writeGenericPointerContainer
130+ }
131+
132+ // ---
133+
134+ func testManualMemoryManagement( ) {
135+ let i1 = sourceInt ( " i1 " )
136+ let r1 = withUnsafePointer ( to: i1, {
137+ ptr in
138+ sink ( arg: ptr) // $ tainted=i1
139+ sink ( arg: ptr [ 0 ] ) // $ tainted=i1
140+ sink ( arg: ptr. pointee) // $ MISSING: tainted=i1
141+ return sourceInt ( " r1 " )
142+ } )
143+ sink ( arg: r1) // $ tainted=r1
144+
145+ var i2 = sourceInt ( " i2 " )
146+ let r2 = withUnsafeMutablePointer ( to: & i2, {
147+ ptr in
148+ sink ( arg: ptr) // $ tainted=i2
149+ sink ( arg: ptr [ 0 ] ) // $ tainted=i2
150+ sink ( arg: ptr. pointee) // $ MISSING: tainted=i2
151+ ptr. pointee = sourceInt ( " i2_overwrite " )
152+ sink ( arg: ptr) // $ SPURIOUS: tainted=i2
153+ sink ( arg: ptr [ 0 ] ) // $ MISSING: tainted=i2_overwrite SPURIOUS: tainted=i2
154+ sink ( arg: ptr. pointee) // $ tainted=i2_overwrite
155+ return sourceInt ( " r2 " )
156+ } )
157+ sink ( arg: r2) // $ tainted=r2
158+ sink ( arg: i2) // $ MISSING: tainted=i2_overwrite SPURIOUS: tainted=i2
159+
160+ let i3 = sourceInt ( " i3 " )
161+ let r3 = withUnsafeBytes ( of: i3, {
162+ ptr in
163+ sink ( arg: ptr) // $ tainted=i3
164+ sink ( arg: ptr [ 0 ] ) // $ tainted=i3
165+ ptr. withMemoryRebound ( to: Int . self, {
166+ buffer in
167+ sink ( arg: buffer) // $ tainted=i3
168+ sink ( arg: buffer [ 0 ] ) // $ tainted=i3
169+ } )
170+ let buffer2 = ptr. bindMemory ( to: Int . self)
171+ sink ( arg: buffer2) // $ tainted=i3
172+ sink ( arg: buffer2 [ 0 ] ) // $ tainted=i3
173+ return sourceInt ( " r3 " )
174+ } )
175+ sink ( arg: r3) // $ tainted=r3
176+
177+ var i4 = sourceInt ( " i4 " )
178+ let r4 = withUnsafeMutableBytes ( of: & i4, {
179+ ptr in
180+ sink ( arg: ptr) // $ tainted=i4
181+ sink ( arg: ptr [ 0 ] ) // $ tainted=i4
182+ ptr [ 0 ] = sourceUInt8 ( " i4_partialwrite " )
183+ sink ( arg: ptr) // $ tainted=i4_partialwrite tainted=i4
184+ sink ( arg: ptr [ 0 ] ) // $ tainted=i4_partialwrite SPURIOUS: tainted=i4
185+ return sourceInt ( " r4 " )
186+ } )
187+ sink ( arg: r4) // $ tainted=r4
188+ sink ( arg: i4) // $ tainted=i4 tainted=i4_partialwrite
189+
190+ let r5 = withUnsafeTemporaryAllocation ( of: Int . self, capacity: 10 , {
191+ buffer in
192+ sink ( arg: buffer)
193+ sink ( arg: buffer [ 0 ] )
194+ buffer [ 0 ] = sourceInt ( " buffer5 " )
195+ sink ( arg: buffer) // $ tainted=buffer5
196+ sink ( arg: buffer [ 0 ] ) // $ tainted=buffer5
197+ return sourceInt ( " r5 " )
198+ } )
199+ sink ( arg: r5) // $ tainted=r5
200+
201+ let r6 = withExtendedLifetime ( sourceInt ( " i6 " ) , {
202+ return sourceInt ( " r6 " )
203+ } )
204+ sink ( arg: r6) // $ tainted=r6
129205}
0 commit comments