|
| 1 | +// --- stubs --- |
| 2 | +struct URL {} |
1 | 3 |
|
2 |
| -class Data |
| 4 | +class NSData {} |
| 5 | + |
| 6 | +protocol SortComparator { |
| 7 | + associatedtype Compared |
| 8 | +} |
| 9 | +struct Data |
3 | 10 | {
|
| 11 | + struct Base64EncodingOptions : OptionSet { let rawValue: Int } |
| 12 | + struct Base64DecodingOptions : OptionSet { let rawValue: Int } |
| 13 | + enum Deallocator { case none } |
| 14 | + struct ReadingOptions : OptionSet { let rawValue: Int } |
| 15 | + typealias Index = Int |
4 | 16 | init<S>(_ elements: S) {}
|
| 17 | + init(base64Encoded: Data, options: Data.Base64DecodingOptions) {} |
| 18 | + init<SourceType>(buffer: UnsafeBufferPointer<SourceType>) {} |
| 19 | + init<SourceType>(buffer: UnsafeMutablePointer<SourceType>) {} |
| 20 | + init(bytes: UnsafeRawPointer, count: Int) {} |
| 21 | + init(bytesNoCopy: UnsafeRawPointer, count: Int, deallocator: Data.Deallocator) {} |
| 22 | + init(contentsOf: URL, options: ReadingOptions) {} |
| 23 | + init(referencing: NSData) {} |
| 24 | + func append(_: Data) {} |
| 25 | + func append(_: UInt8) {} |
| 26 | + func append<SourceType>(_: UnsafeBufferPointer<SourceType>) {} |
| 27 | + func append(_: UnsafePointer<UInt8>, count: Int) {} |
| 28 | + func append(contentsOf: [UInt8]) {} |
| 29 | + func append<S>(contentsOf: S) {} |
| 30 | + func base64EncodedData(options: Data.Base64EncodingOptions) -> Data { return Data("") } |
| 31 | + func base64EncodedString(options: Data.Base64EncodingOptions) -> String { return "" } |
| 32 | + func compactMap<ElementOfResult>(_: (UInt8) -> ElementOfResult) -> [ElementOfResult] { return [] } |
| 33 | + func copyBytes(to: UnsafeMutableRawBufferPointer) {} |
| 34 | + func copyBytes(to: UnsafeMutablePointer<UInt8>, count: Int) {} |
| 35 | + func copyBytes(to: UnsafeMutablePointer<UInt8>, from: Range<Data.Index>) {} |
| 36 | + func flatMap<SegmentOfResult>(_: (UInt8) -> SegmentOfResult) -> [SegmentOfResult.Element] where SegmentOfResult : Sequence { return [] } |
| 37 | + func flatMap<ElementOfResult>(_: (UInt8) -> ElementOfResult?) -> [ElementOfResult] { return [] } |
| 38 | + func insert(_: UInt8, at: Int) {} |
| 39 | + func insert<C>(contentsOf: C, at: Int) where C : Collection, UInt8 == C.Element {} |
| 40 | + func map<T>(_: (UInt8) -> T) -> [T] { return [] } |
| 41 | + func reduce<Result>(into initialResult: Result, _: (inout Result, UInt8) -> ()) -> Result { return initialResult } |
| 42 | + func replace<C, Replacement>(_: C, with: Replacement, maxReplacements: Int) where C : Collection, Replacement : Collection, UInt8 == C.Element, C.Element == Replacement.Element {} |
| 43 | + func replaceSubrange(_: Range<Data.Index>, with: Data) {} |
| 44 | + func replaceSubrange<ByteCollection>(_: Range<Data.Index>, with: ByteCollection) where ByteCollection : Collection, ByteCollection.Element == UInt8 {} |
| 45 | + func replaceSubrange<SourceType>(_: Range<Data.Index>, with: UnsafeBufferPointer<SourceType>) {} |
| 46 | + func replaceSubrange(_: Range<Data.Index>, with: UnsafeRawPointer, count: Int) {} |
| 47 | + func replaceSubrange<C, R>(_: R, with: C) where C : Collection, R : RangeExpression, UInt8 == C.Element, Int == R.Bound {} |
| 48 | + func replacing<C, Replacement>(_: C, with: Replacement, maxReplacements: Int = .max) -> Data where C : Collection, Replacement : Collection, UInt8 == C.Element, C.Element == Replacement.Element { return Data("") } |
| 49 | + func replacing<C, Replacement>(_: C, with: Replacement, subrange: Range<Int>, maxReplacements: Int = .max) -> Data where C : Collection, Replacement : Collection, UInt8 == C.Element, C.Element == Replacement.Element { return Data("") } |
| 50 | + func shuffled() -> [UInt8] { return [] } |
| 51 | + func shuffled<T>(using: inout T) -> [UInt8] { return [] } |
| 52 | + func sorted<Comparator>(using: Comparator) -> [UInt8] where Comparator : SortComparator, UInt8 == Comparator.Compared { return [] } |
| 53 | + func trimmingPrefix<Prefix>(_ prefix: Prefix) -> Data where Prefix : Sequence, UInt8 == Prefix.Element { return Data("") } |
| 54 | + func trimmingPrefix(while: (UInt8) -> Bool) -> Data { return Data("") } |
5 | 55 | }
|
6 | 56 |
|
7 |
| -extension String { |
8 |
| - struct Encoding { |
9 |
| - static let utf8 = Encoding() |
10 |
| - } |
| 57 | +// --- tests --- |
11 | 58 |
|
12 |
| - init?(data: Data, encoding: Encoding) { self.init() } |
| 59 | +class UInt8SortCompartor : SortComparator { |
| 60 | + typealias Compared = UInt8 |
13 | 61 | }
|
14 | 62 |
|
15 |
| -func source() -> String { return "" } |
16 |
| -func sink(arg: Data) {} |
17 |
| -func sink2(arg: String) {} |
| 63 | +func source() -> Any { return "" } |
| 64 | +func sink(arg: Any) {} |
| 65 | +func rng() -> RandomNumberGenerator? { return nil } |
| 66 | +func cmp() -> UInt8SortCompartor? { return nil } |
18 | 67 |
|
19 | 68 | func taintThroughData() {
|
| 69 | + // ";Data;true;init(_:);;;Argument[0];ReturnValue;taint", |
20 | 70 | let dataClean = Data("123456".utf8)
|
21 |
| - let dataTainted = Data(source().utf8) |
| 71 | + let dataTainted = Data((source() as! String).utf8) |
22 | 72 | let dataTainted2 = Data(dataTainted)
|
23 | 73 |
|
24 | 74 | sink(arg: dataClean)
|
25 |
| - sink(arg: dataTainted) // $ MISSING: tainted=13 |
26 |
| - sink(arg: dataTainted2) // $ MISSING: tainted=13 |
| 75 | + sink(arg: dataTainted) // $ MISSING: tainted=71 |
| 76 | + sink(arg: dataTainted2) // $ MISSING: tainted=71 |
| 77 | + |
| 78 | + // ";Data;true;init(base64Encoded:options:);;;Argument[0];ReturnValue;taint", |
| 79 | + let dataTainted3 = Data(base64Encoded: source() as! Data, options: []) |
| 80 | + sink(arg: dataTainted3) // $ tainted=79 |
| 81 | + |
| 82 | + // ";Data;true;init(buffer:);;;Argument[0];ReturnValue;taint", |
| 83 | + let dataTainted4 = Data(buffer: source() as! UnsafeBufferPointer<UInt8>) |
| 84 | + sink(arg: dataTainted4) // $ tainted=83 |
| 85 | + let dataTainted5 = Data(buffer: source() as! UnsafeMutablePointer<UInt8>) |
| 86 | + sink(arg: dataTainted5) // $ tainted=85 |
| 87 | + |
| 88 | + // ";Data;true;init(bytes:count:);;;Argument[0];ReturnValue;taint", |
| 89 | + let dataTainted6 = Data(bytes: source() as! UnsafeRawPointer, count: 0) |
| 90 | + sink(arg: dataTainted6) // $ tainted=89 |
| 91 | + |
| 92 | + // ";Data;true;init(bytesNoCopy:count:deallocator:);;;Argument[0];ReturnValue;taint", |
| 93 | + let dataTainted7 = Data(bytesNoCopy: source() as! UnsafeRawPointer, count: 0, deallocator: Data.Deallocator.none) |
| 94 | + sink(arg: dataTainted7) // $ tainted=93 |
| 95 | + |
| 96 | + // ";Data;true;init(contentsOf:options:);;;Argument[0];ReturnValue;taint", |
| 97 | + let dataTainted8 = Data(contentsOf: source() as! URL, options: []) |
| 98 | + sink(arg: dataTainted8) // $ tainted=97 |
| 99 | + |
| 100 | + // ";Data;true;init(referencing:);;;Argument[0];ReturnValue;taint", |
| 101 | + let dataTainted9 = Data(referencing: source() as! NSData) |
| 102 | + sink(arg: dataTainted9) // $ tainted=101 |
| 103 | + |
| 104 | + // ";Data;true;append(_:);;;Argument[0];Argument[-1];taint", |
| 105 | + let dataTainted10 = Data("") |
| 106 | + dataTainted10.append(source() as! Data) |
| 107 | + sink(arg: dataTainted10) // $ tainted=106 |
| 108 | + |
| 109 | + let dataTainted11 = Data("") |
| 110 | + dataTainted11.append(source() as! UInt8) |
| 111 | + sink(arg: dataTainted11) // $ tainted=110 |
| 112 | + |
| 113 | + let dataTainted12 = Data("") |
| 114 | + dataTainted12.append(source() as! UnsafeBufferPointer<UInt8>) |
| 115 | + sink(arg: dataTainted12) // $ tainted=114 |
| 116 | + |
| 117 | + // ";Data;true;append(_:count:);;;Argument[0];Argument[-1];taint", |
| 118 | + let dataTainted13 = Data("") |
| 119 | + dataTainted13.append(source() as! UnsafePointer<UInt8>, count: 0) |
| 120 | + sink(arg: dataTainted13) // $ tainted=119 |
| 121 | + |
| 122 | + // ";Data;true;append(contentsOf:);;;Argument[0];Argument[-1];taint", |
| 123 | + let dataTainted14 = Data("") |
| 124 | + dataTainted14.append(contentsOf: source() as! [UInt8]) |
| 125 | + sink(arg: dataTainted14) // $ tainted=124 |
| 126 | + |
| 127 | + // ";Data;true;base64EncodedData(options:);;;Argument[-1];ReturnValue;taint", |
| 128 | + let dataTainted15 = source() as! Data |
| 129 | + sink(arg: dataTainted15.base64EncodedData(options: [])) // $ tainted=128 |
| 130 | + |
| 131 | + // ";Data;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint", |
| 132 | + let dataTainted16 = source() as! Data |
| 133 | + sink(arg: dataTainted16.base64EncodedString(options: [])) // $ tainted=132 |
| 134 | + |
| 135 | + // ";Data;true;compactMap(_:);;;Argument[-1];ReturnValue;taint", |
| 136 | + let dataTainted17 = source() as! Data |
| 137 | + let compactMapped: [Int] = dataTainted17.compactMap { str in Int(str) } |
| 138 | + sink(arg: compactMapped) // $ tainted=136 |
| 139 | + |
| 140 | + // ";Data;true;copyBytes(to:);;;Argument[-1];Argument[0];taint", |
| 141 | + let dataTainted18 = source() as! Data |
| 142 | + let pointerTainted18 = UnsafeMutableRawBufferPointer.allocate(byteCount: 0, alignment: 0) |
| 143 | + dataTainted18.copyBytes(to: pointerTainted18) |
| 144 | + sink(arg: pointerTainted18) // $ tainted=141 |
| 145 | + |
| 146 | + // ";Data;true;copyBytes(to:count:);;;Argument[-1];Argument[0];taint", |
| 147 | + let dataTainted19 = source() as! Data |
| 148 | + let pointerTainted19 = UnsafeMutablePointer<UInt8>.allocate(capacity: 0) |
| 149 | + dataTainted19.copyBytes(to: pointerTainted19, count: 0) |
| 150 | + sink(arg: pointerTainted19) // $ MISSING: tainted=147 |
| 151 | + |
| 152 | + // ";Data;true;copyBytes(to:from:);;;Argument[-1];Argument[0];taint", |
| 153 | + let dataTainted20 = source() as! Data |
| 154 | + let pointerTainted20 = UnsafeMutablePointer<UInt8>.allocate(capacity: 0) |
| 155 | + dataTainted20.copyBytes(to: pointerTainted20, from: 0..<1) |
| 156 | + sink(arg: pointerTainted20) // $ MISSING: tainted=153 |
| 157 | + |
| 158 | + // ";Data;true;flatMap(_:);;;Argument[-1];ReturnValue;taint", |
| 159 | + let dataTainted21 = source() as! Data |
| 160 | + let flatMapped = dataTainted21.flatMap { Array(repeating: $0, count: 0) } |
| 161 | + sink(arg: flatMapped) // $ tainted=159 |
| 162 | + |
| 163 | + let dataTainted22 = source() as! Data |
| 164 | + let flatMapped2 = dataTainted22.flatMap { str in Int(str) } |
| 165 | + sink(arg: flatMapped2) // $ tainted=163 |
| 166 | + |
| 167 | + // ";Data;true;insert(_:at:);;;Argument[0];Argument[-1];taint", |
| 168 | + let dataTainted23 = Data("") |
| 169 | + dataTainted23.insert(source() as! UInt8, at: 0) |
| 170 | + sink(arg: dataTainted23) // $ tainted=169 |
| 171 | + |
| 172 | + // ";Data;true;insert(contentsOf:at:);;;Argument[0];Argument[-1];taint", |
| 173 | + let dataTainted24 = Data("") |
| 174 | + dataTainted24.insert(contentsOf: source() as! [UInt8], at: 0) |
| 175 | + sink(arg: dataTainted24) // $ tainted=174 |
| 176 | + |
| 177 | + // ";Data;true;map(_:);;;Argument[-1];ReturnValue;taint", |
| 178 | + let dataTainted25 = source() as! Data |
| 179 | + let mapped = dataTainted25.map { $0 } |
| 180 | + sink(arg: mapped) // $ tainted=178 |
| 181 | + |
| 182 | + // ";Data;true;reduce(into:_:);;;Argument[-1];ReturnValue;taint", |
| 183 | + let dataTainted26 = source() as! Data |
| 184 | + let reduced = dataTainted26.reduce(into: [:]) { c, i in c[i, default: 0] += 1 } |
| 185 | + sink(arg: reduced) // $ tainted=183 |
| 186 | + |
| 187 | + // ";Data;true;replace(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint", |
| 188 | + let dataTainted27 = Data("") |
| 189 | + dataTainted27.replace([0], with: source() as! [UInt8], maxReplacements: .max) |
| 190 | + sink(arg: dataTainted27) // $ tainted=189 |
| 191 | + |
| 192 | + // ";Data;true;replaceSubrange(_:with:);;;Argument[1];Argument[-1];taint", |
| 193 | + let dataTainted28 = Data("") |
| 194 | + dataTainted28.replaceSubrange(1..<3, with: source() as! Data) |
| 195 | + sink(arg: dataTainted28) // $ tainted=194 |
| 196 | + |
| 197 | + let dataTainted29 = Data("") |
| 198 | + dataTainted29.replaceSubrange(1..<3, with: source() as! [UInt8]) |
| 199 | + sink(arg: dataTainted29) // $ tainted=198 |
| 200 | + |
| 201 | + let dataTainted30 = Data("") |
| 202 | + dataTainted30.replaceSubrange(1..<3, with: source() as! UnsafeBufferPointer<UInt8>) |
| 203 | + sink(arg: dataTainted30) // $ tainted=202 |
| 204 | + |
| 205 | + // ";Data;true;replaceSubrange(_:with:count:);;;Argument[1];Argument[-1];taint", |
| 206 | + let dataTainted31 = Data("") |
| 207 | + dataTainted31.replaceSubrange(1..<3, with: source() as! UnsafeRawPointer, count: 0) |
| 208 | + sink(arg: dataTainted31) // $ tainted=207 |
| 209 | + |
| 210 | + // ";Data;true;replacing(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint", |
| 211 | + let dataTainted32 = Data("") |
| 212 | + dataTainted32.replacing([0], with: source() as! [UInt8], maxReplacements: 0) |
| 213 | + sink(arg: dataTainted32) // $ tainted=212 |
| 214 | + |
| 215 | + // ";Data;true;replacing(_:with:subrange:maxReplacements:);;;Argument[1];Argument[-1];taint", |
| 216 | + let dataTainted33 = Data("") |
| 217 | + dataTainted33.replacing([0], with: source() as! [UInt8], subrange: 1..<3, maxReplacements: 0) |
| 218 | + sink(arg: dataTainted33) // $ tainted=217 |
| 219 | + |
| 220 | + // ";Data;true;shuffled();;;Argument[-1];ReturnValue;taint", |
| 221 | + let dataTainted34 = source() as! Data |
| 222 | + sink(arg: dataTainted34.shuffled()) // $ tainted=221 |
| 223 | + |
| 224 | + // ";Data;true;shuffled(using:);;;Argument[-1];ReturnValue;taint", |
| 225 | + let dataTainted35 = source() as! Data |
| 226 | + var rng = rng()! |
| 227 | + sink(arg: dataTainted35.shuffled(using: &rng)) // $ tainted=225 |
| 228 | + |
| 229 | + // ";Data;true;sorted(using:);;;Argument[-1];ReturnValue;taint", |
| 230 | + let dataTainted36 = source() as! Data |
| 231 | + sink(arg: dataTainted36.sorted(using: cmp()!)) // $ tainted=230 |
| 232 | + |
| 233 | + // ";Data;true;trimmingPrefix(_:);;;Argument[-1];ReturnValue;taint", |
| 234 | + let dataTainted37 = source() as! Data |
| 235 | + sink(arg: dataTainted37.trimmingPrefix([0])) // $ tainted=234 |
27 | 236 |
|
28 |
| - let stringClean = String(data: dataClean, encoding: String.Encoding.utf8) |
29 |
| - let stringTainted = String(data: dataTainted, encoding: String.Encoding.utf8) |
| 237 | + // ";Data;true;trimmingPrefix(while:);;;Argument[-1];ReturnValue;taint" |
| 238 | + let dataTainted38 = source() as! Data |
| 239 | + sink(arg: dataTainted38.trimmingPrefix { _ in false }) // $ tainted=238 |
30 | 240 |
|
31 |
| - sink2(arg: stringClean!) // $ MISSING: tainted=13 |
32 |
| - sink2(arg: stringTainted!) // $ MISSING: tainted=13 |
33 | 241 | }
|
0 commit comments