11// --- stubs ---
22
3+ class NSObject { }
4+
35func NSLog( _ format: String , _ args: CVarArg ... ) { }
46func NSLogv( _ format: String , _ args: CVaListPointer ) { }
57func getVaList( _ args: [ CVarArg ] ) -> CVaListPointer { return CVaListPointer ( _fromUnsafeMutablePointer: UnsafeMutablePointer ( bitPattern: 0 ) !) }
@@ -78,63 +80,88 @@ struct Logger {
7880 func warning( _: OSLogMessage ) { }
7981 func fault( _: OSLogMessage ) { }
8082 func critical( _: OSLogMessage ) { }
83+ }
8184
85+ class OSLog : NSObject {
86+ static let `default` = OSLog ( rawValue: 0 )
87+ let rawValue : UInt8
88+ init ( rawValue: UInt8 ) { self . rawValue = rawValue}
8289}
8390
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+
84102// --- tests ---
85103
86104func 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
103125
104126 let bankAccount : Int = 0
105127 let log = Logger ( )
106128 // 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+
138165}
139166
140167class MyClass {
@@ -148,16 +175,16 @@ func doSomething(password: String) { }
148175func test3( x: String ) {
149176 // alternative evidence of sensitivity...
150177
151- NSLog ( x) // $ MISSING: hasCleartextLogging=152
178+ NSLog ( x) // $ MISSING: hasCleartextLogging=179
152179 doSomething ( password: x) ;
153- NSLog ( x) // $ hasCleartextLogging=152
180+ NSLog ( x) // $ hasCleartextLogging=179
154181
155182 let y = getPassword ( ) ;
156- NSLog ( y) // $ hasCleartextLogging=155
183+ NSLog ( y) // $ hasCleartextLogging=182
157184
158185 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
161188}
162189
163190struct MyOuter {
@@ -170,6 +197,87 @@ struct MyOuter {
170197}
171198
172199func 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+ }
175283}
0 commit comments