1
1
// --- stubs ---
2
2
3
+ class NSObject { }
4
+
3
5
func NSLog( _ format: String , _ args: CVarArg ... ) { }
4
6
func NSLogv( _ format: String , _ args: CVaListPointer ) { }
5
7
func getVaList( _ args: [ CVarArg ] ) -> CVaListPointer { return CVaListPointer ( _fromUnsafeMutablePointer: UnsafeMutablePointer ( bitPattern: 0 ) !) }
@@ -78,63 +80,88 @@ struct Logger {
78
80
func warning( _: OSLogMessage ) { }
79
81
func fault( _: OSLogMessage ) { }
80
82
func critical( _: OSLogMessage ) { }
83
+ }
81
84
85
+ class OSLog : NSObject {
86
+ static let `default` = OSLog ( rawValue: 0 )
87
+ let rawValue : UInt8
88
+ init ( rawValue: UInt8 ) { self . rawValue = rawValue}
82
89
}
83
90
91
+ extension String : CVarArg {
92
+ public var _cVarArgEncoding : [ Int ] { get { return [ ] } }
93
+ }
94
+
95
+ // from ObjC API; slightly simplified.
96
+ func os_log( _ message: StaticString ,
97
+ dso: UnsafeRawPointer ? = nil ,
98
+ log: OSLog = . default,
99
+ type: OSLogType = . default,
100
+ _ args: CVarArg ... ) { }
101
+
84
102
// --- tests ---
85
103
86
104
func test1( password: String , passwordHash : String , passphrase: String , pass_phrase: String ) {
87
- print ( password) // $ hasCleartextLogging=87
88
- print ( password, separator: " " ) // $ $ hasCleartextLogging=88
89
- print ( " " , separator: password) // $ hasCleartextLogging=89
90
- print ( password, separator: " " , terminator: " " ) // $ hasCleartextLogging=90
91
- print ( " " , separator: password, terminator: " " ) // $ hasCleartextLogging=91
92
- print ( " " , separator: " " , terminator: password) // $ hasCleartextLogging=92
93
- print ( passwordHash) // Safe
94
-
95
- NSLog ( password) // $ hasCleartextLogging=95
96
- NSLog ( " %@ " , password as! CVarArg ) // $ hasCleartextLogging=96
97
- NSLog ( " %@ %@ " , " " as! CVarArg , password as! CVarArg ) // $ hasCleartextLogging=97
98
- NSLog ( " \( password) " ) // $ hasCleartextLogging=98
99
- NSLogv ( " %@ " , getVaList ( [ password as! CVarArg ] ) ) // $ hasCleartextLogging=99
100
- NSLogv ( " %@ %@ " , getVaList ( [ " " as! CVarArg , password as! CVarArg ] ) ) // $ hasCleartextLogging=100
101
- NSLog ( passwordHash) // SAfe
102
- NSLogv ( " %@ " , getVaList ( [ passwordHash as! CVarArg ] ) ) // Safe
105
+ print ( password) // $ hasCleartextLogging=105
106
+ print ( password, separator: " " ) // $ $ hasCleartextLogging=106
107
+ print ( " " , separator: password) // $ hasCleartextLogging=107
108
+ print ( password, separator: " " , terminator: " " ) // $ hasCleartextLogging=108
109
+ print ( " " , separator: password, terminator: " " ) // $ hasCleartextLogging=109
110
+ print ( " " , separator: " " , terminator: password) // $ hasCleartextLogging=110
111
+ print ( passwordHash) // safe
112
+
113
+ debugPrint ( password) // $ hasCleartextLogging=113
114
+
115
+ dump ( password) // $ hasCleartextLogging=115
116
+
117
+ NSLog ( password) // $ hasCleartextLogging=117
118
+ NSLog ( " %@ " , password) // $ hasCleartextLogging=118
119
+ NSLog ( " %@ %@ " , " " , password) // $ hasCleartextLogging=119
120
+ NSLog ( " \( password) " ) // $ hasCleartextLogging=120
121
+ NSLogv ( " %@ " , getVaList ( [ password] ) ) // $ hasCleartextLogging=121
122
+ NSLogv ( " %@ %@ " , getVaList ( [ " " , password] ) ) // $ hasCleartextLogging=122
123
+ NSLog ( passwordHash) // safe
124
+ NSLogv ( " %@ " , getVaList ( [ passwordHash] ) ) // safe
103
125
104
126
let bankAccount : Int = 0
105
127
let log = Logger ( )
106
128
// These MISSING test cases will be fixed when we properly generate the CFG around autoclosures.
107
- log. log ( " \( password) " ) // Safe
108
- log. log ( " \( password, privacy: . auto) " ) // Safe
109
- log. log ( " \( password, privacy: . private) " ) // Safe
110
- log. log ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=110
111
- log. log ( " \( passwordHash, privacy: . public) " ) // Safe
112
- log. log ( " \( password, privacy: . sensitive) " ) // Safe
113
- log. log ( " \( bankAccount) " ) // $ MISSING: hasCleartextLogging=113
114
- log. log ( " \( bankAccount, privacy: . auto) " ) // $ MISSING: hasCleartextLogging=114
115
- log. log ( " \( bankAccount, privacy: . private) " ) // Safe
116
- log. log ( " \( bankAccount, privacy: . public) " ) // $ MISSING: hasCleartextLogging=116
117
- log. log ( " \( bankAccount, privacy: . sensitive) " ) // Safe
118
- log. log ( level: . default, " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=118
119
- log. trace ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=119
120
- log. trace ( " \( passwordHash, privacy: . public) " ) // Safe
121
- log. debug ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=121
122
- log. debug ( " \( passwordHash, privacy: . public) " ) // Safe
123
- log. info ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=123
124
- log. info ( " \( passwordHash, privacy: . public) " ) // Safe
125
- log. notice ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=125
126
- log. notice ( " \( passwordHash, privacy: . public) " ) // Safe
127
- log. warning ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=127
128
- log. warning ( " \( passwordHash, privacy: . public) " ) // Safe
129
- log. error ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=129
130
- log. error ( " \( passwordHash, privacy: . public) " ) // Safe
131
- log. critical ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=131
132
- log. critical ( " \( passwordHash, privacy: . public) " ) // Safe
133
- log. fault ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=133
134
- log. fault ( " \( passwordHash, privacy: . public) " ) // Safe
135
-
136
- NSLog ( passphrase) // $ hasCleartextLogging=136
137
- NSLog ( pass_phrase) // $ hasCleartextLogging=137
129
+ log. log ( " \( password) " ) // safe
130
+ log. log ( " \( password, privacy: . auto) " ) // safe
131
+ log. log ( " \( password, privacy: . private) " ) // safe
132
+ log. log ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=132
133
+ log. log ( " \( passwordHash, privacy: . public) " ) // safe
134
+ log. log ( " \( password, privacy: . sensitive) " ) // safe
135
+ log. log ( " \( bankAccount) " ) // $ MISSING: hasCleartextLogging=135
136
+ log. log ( " \( bankAccount, privacy: . auto) " ) // $ MISSING: hasCleartextLogging=136
137
+ log. log ( " \( bankAccount, privacy: . private) " ) // safe
138
+ log. log ( " \( bankAccount, privacy: . public) " ) // $ MISSING: hasCleartextLogging=138
139
+ log. log ( " \( bankAccount, privacy: . sensitive) " ) // safe
140
+ log. log ( level: . default, " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=140
141
+ log. trace ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=141
142
+ log. trace ( " \( passwordHash, privacy: . public) " ) // safe
143
+ log. debug ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=143
144
+ log. debug ( " \( passwordHash, privacy: . public) " ) // safe
145
+ log. info ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=145
146
+ log. info ( " \( passwordHash, privacy: . public) " ) // safe
147
+ log. notice ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=147
148
+ log. notice ( " \( passwordHash, privacy: . public) " ) // safe
149
+ log. warning ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=149
150
+ log. warning ( " \( passwordHash, privacy: . public) " ) // safe
151
+ log. error ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=151
152
+ log. error ( " \( passwordHash, privacy: . public) " ) // safe
153
+ log. critical ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=153
154
+ log. critical ( " \( passwordHash, privacy: . public) " ) // safe
155
+ log. fault ( " \( password, privacy: . public) " ) // $ MISSING: hasCleartextLogging=155
156
+ log. fault ( " \( passwordHash, privacy: . public) " ) // safe
157
+
158
+ NSLog ( passphrase) // $ hasCleartextLogging=158
159
+ NSLog ( pass_phrase) // $ hasCleartextLogging=159
160
+
161
+ os_log ( " %@ " , log: . default, type: . default, " " ) // safe
162
+ os_log ( " %@ " , log: . default, type: . default, password) // $ hasCleartextLogging=162
163
+ os_log ( " %@ %@ %@ " , log: . default, type: . default, " " , " " , password) // $ hasCleartextLogging=163
164
+
138
165
}
139
166
140
167
class MyClass {
@@ -148,16 +175,16 @@ func doSomething(password: String) { }
148
175
func test3( x: String ) {
149
176
// alternative evidence of sensitivity...
150
177
151
- NSLog ( x) // $ MISSING: hasCleartextLogging=152
178
+ NSLog ( x) // $ MISSING: hasCleartextLogging=179
152
179
doSomething ( password: x) ;
153
- NSLog ( x) // $ hasCleartextLogging=152
180
+ NSLog ( x) // $ hasCleartextLogging=179
154
181
155
182
let y = getPassword ( ) ;
156
- NSLog ( y) // $ hasCleartextLogging=155
183
+ NSLog ( y) // $ hasCleartextLogging=182
157
184
158
185
let z = MyClass ( )
159
- NSLog ( z. harmless) // Safe
160
- NSLog ( z. password) // $ hasCleartextLogging=160
186
+ NSLog ( z. harmless) // safe
187
+ NSLog ( z. password) // $ hasCleartextLogging=187
161
188
}
162
189
163
190
struct MyOuter {
@@ -170,6 +197,87 @@ struct MyOuter {
170
197
}
171
198
172
199
func test3( mo : MyOuter ) {
173
- NSLog ( mo. password. value) // $ hasCleartextLogging=173
174
- NSLog ( mo. harmless. value) // Safe
200
+ // struct members...
201
+
202
+ NSLog ( mo. password. value) // $ hasCleartextLogging=202
203
+ NSLog ( mo. harmless. value) // safe
204
+ }
205
+
206
+ func test4( harmless: String , password: String ) {
207
+ // functions with an `in:` target for the write...
208
+ var myString1 = " "
209
+ var myString2 = " "
210
+ var myString3 = " "
211
+ var myString4 = " "
212
+ var myString5 = " "
213
+ var myString6 = " "
214
+ var myString7 = " "
215
+ var myString8 = " "
216
+ var myString9 = " "
217
+ var myString10 = " "
218
+ var myString11 = " "
219
+ var myString12 = " "
220
+ var myString13 = " "
221
+
222
+ print ( harmless, to: & myString1)
223
+ print ( myString1) // safe
224
+
225
+ print ( password, to: & myString2)
226
+ print ( myString2) // $ hasCleartextLogging=225
227
+
228
+ print ( " log: " + password, to: & myString3)
229
+ print ( myString3) // $ hasCleartextLogging=228
230
+
231
+ debugPrint ( harmless, to: & myString4)
232
+ debugPrint ( myString4) // safe
233
+
234
+ debugPrint ( password, to: & myString5)
235
+ debugPrint ( myString5) // $ hasCleartextLogging=234
236
+
237
+ dump ( harmless, to: & myString6)
238
+ dump ( myString6) // safe
239
+
240
+ dump ( password, to: & myString7)
241
+ dump ( myString7) // $ hasCleartextLogging=240
242
+
243
+ myString8. write ( harmless)
244
+ print ( myString8)
245
+
246
+ myString9. write ( password)
247
+ print ( myString9) // $ hasCleartextLogging=246
248
+
249
+ myString10. write ( harmless)
250
+ myString10. write ( password)
251
+ myString10. write ( harmless)
252
+ print ( myString10) // $ hasCleartextLogging=250
253
+
254
+ harmless. write ( to: & myString11)
255
+ print ( myString11)
256
+
257
+ password. write ( to: & myString12)
258
+ print ( myString12) // $ hasCleartextLogging=257
259
+
260
+ print ( password, to: & myString13) // $ safe - only printed to another string
261
+ debugPrint ( password, to: & myString13) // $ safe - only printed to another string
262
+ dump ( password, to: & myString13) // $ safe - only printed to another string
263
+ myString13. write ( password) // safe - only printed to another string
264
+ password. write ( to: & myString13) // safe - only printed to another string
265
+ }
266
+
267
+ func test5( password: String , caseNum: Int ) {
268
+ // `assert` methods...
269
+ // (these would only be a danger in certain builds)
270
+
271
+ switch caseNum {
272
+ case 0 :
273
+ assert ( false , password) // $ MISSING: hasCleartextLogging=273
274
+ case 1 :
275
+ assertionFailure ( password) // $ MISSING: hasCleartextLogging=275
276
+ case 2 :
277
+ precondition ( false , password) // $ MISSING: hasCleartextLogging=277
278
+ case 3 :
279
+ preconditionFailure ( password) // $ MISSING: hasCleartextLogging=279
280
+ default :
281
+ fatalError ( password) // $ MISSING: hasCleartextLogging=281
282
+ }
175
283
}
0 commit comments