@@ -438,7 +438,7 @@ func taintThroughEncodings() {
438438 } )
439439 tainted. withContiguousStorageIfAvailable ( {
440440 ptr in
441- sink ( arg: ptr)
441+ sink ( arg: ptr) // $ tainted=366
442442 sink ( arg: ptr. baseAddress!) // $ MISSING: tainted=366
443443 } )
444444}
@@ -599,3 +599,52 @@ func untaintedFields() {
599599 sink ( arg: String . defaultCStringEncoding)
600600 sink ( arg: tainted. isContiguousUTF8)
601601}
602+
603+ func callbackWithCleanPointer( ptr: UnsafeBufferPointer < String . Element > ) throws -> Int {
604+ sink ( arg: ptr)
605+
606+ return 0
607+ }
608+
609+ func callbackWithTaintedPointer( ptr: UnsafeBufferPointer < String . Element > ) throws -> Int {
610+ sink ( arg: ptr) // $ tainted=617
611+
612+ return source ( )
613+ }
614+
615+ func furtherTaintThroughCallbacks( ) {
616+ let clean = " "
617+ let tainted = source2 ( )
618+
619+ // return values from the closure (1)
620+ let result1 = clean. withContiguousStorageIfAvailable ( {
621+ ptr in
622+ return 0
623+ } )
624+ sink ( arg: result1!)
625+ let result2 = clean. withContiguousStorageIfAvailable ( {
626+ ptr in
627+ return source ( )
628+ } )
629+ sink ( arg: result2!) // $ tainted=627
630+
631+ // return values from the closure (2)
632+ if let result3 = clean. withContiguousStorageIfAvailable ( {
633+ ptr in
634+ return 0
635+ } ) {
636+ sink ( arg: result3)
637+ }
638+ if let result4 = clean. withContiguousStorageIfAvailable ( {
639+ ptr in
640+ return source ( )
641+ } ) {
642+ sink ( arg: result4) // $ MISSING: tainted=640
643+ }
644+
645+ // using a non-closure function
646+ let result5 = try ? clean. withContiguousStorageIfAvailable ( callbackWithCleanPointer)
647+ sink ( arg: result5!)
648+ let result6 = try ? tainted. withContiguousStorageIfAvailable ( callbackWithTaintedPointer)
649+ sink ( arg: result6!) // $ tainted=612
650+ }
0 commit comments