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