1*f4a2713aSLionel Sambuc// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI %s -verify 2*f4a2713aSLionel Sambuc 3*f4a2713aSLionel Sambuc// Fake typedefs. 4*f4a2713aSLionel Sambuctypedef unsigned int OSStatus; 5*f4a2713aSLionel Sambuctypedef unsigned int SecKeychainAttributeList; 6*f4a2713aSLionel Sambuctypedef unsigned int SecKeychainItemRef; 7*f4a2713aSLionel Sambuctypedef unsigned int SecItemClass; 8*f4a2713aSLionel Sambuctypedef unsigned int UInt32; 9*f4a2713aSLionel Sambuctypedef unsigned int CFTypeRef; 10*f4a2713aSLionel Sambuctypedef unsigned int UInt16; 11*f4a2713aSLionel Sambuctypedef unsigned int SecProtocolType; 12*f4a2713aSLionel Sambuctypedef unsigned int SecAuthenticationType; 13*f4a2713aSLionel Sambuctypedef unsigned int SecKeychainAttributeInfo; 14*f4a2713aSLionel Sambucenum { 15*f4a2713aSLionel Sambuc noErr = 0, 16*f4a2713aSLionel Sambuc GenericError = 1 17*f4a2713aSLionel Sambuc}; 18*f4a2713aSLionel Sambuc 19*f4a2713aSLionel Sambuc// Functions that allocate data. 20*f4a2713aSLionel SambucOSStatus SecKeychainItemCopyContent ( 21*f4a2713aSLionel Sambuc SecKeychainItemRef itemRef, 22*f4a2713aSLionel Sambuc SecItemClass *itemClass, 23*f4a2713aSLionel Sambuc SecKeychainAttributeList *attrList, 24*f4a2713aSLionel Sambuc UInt32 *length, 25*f4a2713aSLionel Sambuc void **outData 26*f4a2713aSLionel Sambuc); 27*f4a2713aSLionel SambucOSStatus SecKeychainFindGenericPassword ( 28*f4a2713aSLionel Sambuc CFTypeRef keychainOrArray, 29*f4a2713aSLionel Sambuc UInt32 serviceNameLength, 30*f4a2713aSLionel Sambuc const char *serviceName, 31*f4a2713aSLionel Sambuc UInt32 accountNameLength, 32*f4a2713aSLionel Sambuc const char *accountName, 33*f4a2713aSLionel Sambuc UInt32 *passwordLength, 34*f4a2713aSLionel Sambuc void **passwordData, 35*f4a2713aSLionel Sambuc SecKeychainItemRef *itemRef 36*f4a2713aSLionel Sambuc); 37*f4a2713aSLionel SambucOSStatus SecKeychainFindInternetPassword ( 38*f4a2713aSLionel Sambuc CFTypeRef keychainOrArray, 39*f4a2713aSLionel Sambuc UInt32 serverNameLength, 40*f4a2713aSLionel Sambuc const char *serverName, 41*f4a2713aSLionel Sambuc UInt32 securityDomainLength, 42*f4a2713aSLionel Sambuc const char *securityDomain, 43*f4a2713aSLionel Sambuc UInt32 accountNameLength, 44*f4a2713aSLionel Sambuc const char *accountName, 45*f4a2713aSLionel Sambuc UInt32 pathLength, 46*f4a2713aSLionel Sambuc const char *path, 47*f4a2713aSLionel Sambuc UInt16 port, 48*f4a2713aSLionel Sambuc SecProtocolType protocol, 49*f4a2713aSLionel Sambuc SecAuthenticationType authenticationType, 50*f4a2713aSLionel Sambuc UInt32 *passwordLength, 51*f4a2713aSLionel Sambuc void **passwordData, 52*f4a2713aSLionel Sambuc SecKeychainItemRef *itemRef 53*f4a2713aSLionel Sambuc); 54*f4a2713aSLionel SambucOSStatus SecKeychainItemCopyAttributesAndData ( 55*f4a2713aSLionel Sambuc SecKeychainItemRef itemRef, 56*f4a2713aSLionel Sambuc SecKeychainAttributeInfo *info, 57*f4a2713aSLionel Sambuc SecItemClass *itemClass, 58*f4a2713aSLionel Sambuc SecKeychainAttributeList **attrList, 59*f4a2713aSLionel Sambuc UInt32 *length, 60*f4a2713aSLionel Sambuc void **outData 61*f4a2713aSLionel Sambuc); 62*f4a2713aSLionel Sambuc 63*f4a2713aSLionel Sambuc// Functions which free data. 64*f4a2713aSLionel SambucOSStatus SecKeychainItemFreeContent ( 65*f4a2713aSLionel Sambuc SecKeychainAttributeList *attrList, 66*f4a2713aSLionel Sambuc void *data 67*f4a2713aSLionel Sambuc); 68*f4a2713aSLionel SambucOSStatus SecKeychainItemFreeAttributesAndData ( 69*f4a2713aSLionel Sambuc SecKeychainAttributeList *attrList, 70*f4a2713aSLionel Sambuc void *data 71*f4a2713aSLionel Sambuc); 72*f4a2713aSLionel Sambuc 73*f4a2713aSLionel Sambucvoid errRetVal() { 74*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 75*f4a2713aSLionel Sambuc OSStatus st = 0; 76*f4a2713aSLionel Sambuc UInt32 length; 77*f4a2713aSLionel Sambuc void *outData; 78*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 79*f4a2713aSLionel Sambuc if (st == GenericError) 80*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(ptr, outData); // expected-warning{{Only call free if a valid (non-NULL) buffer was returned}} 81*f4a2713aSLionel Sambuc} // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}} 82*f4a2713aSLionel Sambuc 83*f4a2713aSLionel Sambuc// If null is passed in, the data is not allocated, so no need for the matching free. 84*f4a2713aSLionel Sambucvoid fooDoNotReportNull() { 85*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 86*f4a2713aSLionel Sambuc OSStatus st = 0; 87*f4a2713aSLionel Sambuc UInt32 *length = 0; 88*f4a2713aSLionel Sambuc void **outData = 0; 89*f4a2713aSLionel Sambuc SecKeychainItemCopyContent(2, ptr, ptr, 0, 0); 90*f4a2713aSLionel Sambuc SecKeychainItemCopyContent(2, ptr, ptr, length, outData); 91*f4a2713aSLionel Sambuc}// no-warning 92*f4a2713aSLionel Sambuc 93*f4a2713aSLionel Sambucvoid doubleAlloc() { 94*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 95*f4a2713aSLionel Sambuc OSStatus st = 0; 96*f4a2713aSLionel Sambuc UInt32 length; 97*f4a2713aSLionel Sambuc void *outData; 98*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 99*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); // expected-warning {{Allocated data should be released before another call to the allocator:}} 100*f4a2713aSLionel Sambuc if (st == noErr) 101*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(ptr, outData); 102*f4a2713aSLionel Sambuc} 103*f4a2713aSLionel Sambuc 104*f4a2713aSLionel Sambucvoid fooOnlyFree() { 105*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 106*f4a2713aSLionel Sambuc OSStatus st = 0; 107*f4a2713aSLionel Sambuc UInt32 length; 108*f4a2713aSLionel Sambuc void *outData = &length; 109*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(ptr, outData);// expected-warning{{Trying to free data which has not been allocated}} 110*f4a2713aSLionel Sambuc} 111*f4a2713aSLionel Sambuc 112*f4a2713aSLionel Sambuc// Do not warn if undefined value is passed to a function. 113*f4a2713aSLionel Sambucvoid fooOnlyFreeUndef() { 114*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 115*f4a2713aSLionel Sambuc OSStatus st = 0; 116*f4a2713aSLionel Sambuc UInt32 length; 117*f4a2713aSLionel Sambuc void *outData; 118*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(ptr, outData); 119*f4a2713aSLionel Sambuc}// no-warning 120*f4a2713aSLionel Sambuc 121*f4a2713aSLionel Sambuc// Do not warn if the address is a parameter in the enclosing function. 122*f4a2713aSLionel Sambucvoid fooOnlyFreeParam(void *attrList, void* X) { 123*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(attrList, X); 124*f4a2713aSLionel Sambuc}// no-warning 125*f4a2713aSLionel Sambuc 126*f4a2713aSLionel Sambuc// If we are returning the value, do not report. 127*f4a2713aSLionel Sambucvoid* returnContent() { 128*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 129*f4a2713aSLionel Sambuc OSStatus st = 0; 130*f4a2713aSLionel Sambuc UInt32 length; 131*f4a2713aSLionel Sambuc void *outData; 132*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 133*f4a2713aSLionel Sambuc return outData; 134*f4a2713aSLionel Sambuc} // no-warning 135*f4a2713aSLionel Sambuc 136*f4a2713aSLionel Sambuc// Password was passed in as an argument and does not have to be deleted. 137*f4a2713aSLionel SambucOSStatus getPasswordAndItem(void** password, UInt32* passwordLength) { 138*f4a2713aSLionel Sambuc OSStatus err; 139*f4a2713aSLionel Sambuc SecKeychainItemRef item; 140*f4a2713aSLionel Sambuc err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx", 141*f4a2713aSLionel Sambuc passwordLength, password, &item); 142*f4a2713aSLionel Sambuc return err; 143*f4a2713aSLionel Sambuc} // no-warning 144*f4a2713aSLionel Sambuc 145*f4a2713aSLionel Sambuc// Make sure we do not report an error if we call free only if password != 0. 146*f4a2713aSLionel Sambuc// Also, do not report double allocation if first allocation returned an error. 147*f4a2713aSLionel SambucOSStatus testSecKeychainFindGenericPassword(UInt32* passwordLength, 148*f4a2713aSLionel Sambuc CFTypeRef keychainOrArray, SecProtocolType protocol, 149*f4a2713aSLionel Sambuc SecAuthenticationType authenticationType) { 150*f4a2713aSLionel Sambuc OSStatus err; 151*f4a2713aSLionel Sambuc SecKeychainItemRef item; 152*f4a2713aSLionel Sambuc void *password; 153*f4a2713aSLionel Sambuc err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx", 154*f4a2713aSLionel Sambuc passwordLength, &password, &item); 155*f4a2713aSLionel Sambuc if( err == GenericError ) { 156*f4a2713aSLionel Sambuc err = SecKeychainFindInternetPassword(keychainOrArray, 157*f4a2713aSLionel Sambuc 16, "server", 16, "domain", 16, "account", 158*f4a2713aSLionel Sambuc 16, "path", 222, protocol, authenticationType, 159*f4a2713aSLionel Sambuc passwordLength, &(password), 0); 160*f4a2713aSLionel Sambuc } 161*f4a2713aSLionel Sambuc 162*f4a2713aSLionel Sambuc if (err == noErr && password) { 163*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(0, password); 164*f4a2713aSLionel Sambuc } 165*f4a2713aSLionel Sambuc return err; 166*f4a2713aSLionel Sambuc} 167*f4a2713aSLionel Sambuc 168*f4a2713aSLionel Sambucint apiMismatch(SecKeychainItemRef itemRef, 169*f4a2713aSLionel Sambuc SecKeychainAttributeInfo *info, 170*f4a2713aSLionel Sambuc SecItemClass *itemClass) { 171*f4a2713aSLionel Sambuc OSStatus st = 0; 172*f4a2713aSLionel Sambuc SecKeychainAttributeList *attrList; 173*f4a2713aSLionel Sambuc UInt32 length; 174*f4a2713aSLionel Sambuc void *outData; 175*f4a2713aSLionel Sambuc 176*f4a2713aSLionel Sambuc st = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass, 177*f4a2713aSLionel Sambuc &attrList, &length, &outData); 178*f4a2713aSLionel Sambuc if (st == noErr) 179*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(attrList, outData); // expected-warning{{Deallocator doesn't match the allocator}} 180*f4a2713aSLionel Sambuc return 0; 181*f4a2713aSLionel Sambuc} 182*f4a2713aSLionel Sambuc 183*f4a2713aSLionel Sambucint ErrorCodesFromDifferentAPISDoNotInterfere(SecKeychainItemRef itemRef, 184*f4a2713aSLionel Sambuc SecKeychainAttributeInfo *info, 185*f4a2713aSLionel Sambuc SecItemClass *itemClass) { 186*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 187*f4a2713aSLionel Sambuc OSStatus st = 0; 188*f4a2713aSLionel Sambuc UInt32 length; 189*f4a2713aSLionel Sambuc void *outData; 190*f4a2713aSLionel Sambuc OSStatus st2 = 0; 191*f4a2713aSLionel Sambuc SecKeychainAttributeList *attrList; 192*f4a2713aSLionel Sambuc UInt32 length2; 193*f4a2713aSLionel Sambuc void *outData2; 194*f4a2713aSLionel Sambuc 195*f4a2713aSLionel Sambuc st2 = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass, 196*f4a2713aSLionel Sambuc &attrList, &length2, &outData2); 197*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 198*f4a2713aSLionel Sambuc if (st == noErr) { 199*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(ptr, outData); 200*f4a2713aSLionel Sambuc if (st2 == noErr) { 201*f4a2713aSLionel Sambuc SecKeychainItemFreeAttributesAndData(attrList, outData2); 202*f4a2713aSLionel Sambuc } 203*f4a2713aSLionel Sambuc } 204*f4a2713aSLionel Sambuc return 0; // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeAttributesAndData'}} 205*f4a2713aSLionel Sambuc} 206*f4a2713aSLionel Sambuc 207*f4a2713aSLionel Sambucint foo(CFTypeRef keychainOrArray, SecProtocolType protocol, 208*f4a2713aSLionel Sambuc SecAuthenticationType authenticationType, SecKeychainItemRef *itemRef) { 209*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 210*f4a2713aSLionel Sambuc OSStatus st = 0; 211*f4a2713aSLionel Sambuc 212*f4a2713aSLionel Sambuc UInt32 length; 213*f4a2713aSLionel Sambuc void *outData[5]; 214*f4a2713aSLionel Sambuc 215*f4a2713aSLionel Sambuc st = SecKeychainFindInternetPassword(keychainOrArray, 216*f4a2713aSLionel Sambuc 16, "server", 16, "domain", 16, "account", 217*f4a2713aSLionel Sambuc 16, "path", 222, protocol, authenticationType, 218*f4a2713aSLionel Sambuc &length, &(outData[3]), itemRef); 219*f4a2713aSLionel Sambuc if (length == 5) { 220*f4a2713aSLionel Sambuc if (st == noErr) 221*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(ptr, outData[3]); 222*f4a2713aSLionel Sambuc } 223*f4a2713aSLionel Sambuc if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}} 224*f4a2713aSLionel Sambuc length++; 225*f4a2713aSLionel Sambuc } 226*f4a2713aSLionel Sambuc return 0; 227*f4a2713aSLionel Sambuc}// no-warning 228*f4a2713aSLionel Sambuc 229*f4a2713aSLionel Sambucvoid free(void *ptr); 230*f4a2713aSLionel Sambucvoid deallocateWithFree() { 231*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 232*f4a2713aSLionel Sambuc OSStatus st = 0; 233*f4a2713aSLionel Sambuc UInt32 length; 234*f4a2713aSLionel Sambuc void *outData; 235*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 236*f4a2713aSLionel Sambuc if (st == noErr) 237*f4a2713aSLionel Sambuc free(outData); // expected-warning{{Deallocator doesn't match the allocator: 'SecKeychainItemFreeContent' should be used}} 238*f4a2713aSLionel Sambuc} 239*f4a2713aSLionel Sambuc 240*f4a2713aSLionel Sambuc// Typesdefs for CFStringCreateWithBytesNoCopy. 241*f4a2713aSLionel Sambuctypedef char uint8_t; 242*f4a2713aSLionel Sambuctypedef signed long CFIndex; 243*f4a2713aSLionel Sambuctypedef UInt32 CFStringEncoding; 244*f4a2713aSLionel Sambuctypedef unsigned Boolean; 245*f4a2713aSLionel Sambuctypedef const struct __CFString * CFStringRef; 246*f4a2713aSLionel Sambuctypedef const struct __CFAllocator * CFAllocatorRef; 247*f4a2713aSLionel Sambucextern const CFAllocatorRef kCFAllocatorDefault; 248*f4a2713aSLionel Sambucextern const CFAllocatorRef kCFAllocatorSystemDefault; 249*f4a2713aSLionel Sambucextern const CFAllocatorRef kCFAllocatorMalloc; 250*f4a2713aSLionel Sambucextern const CFAllocatorRef kCFAllocatorMallocZone; 251*f4a2713aSLionel Sambucextern const CFAllocatorRef kCFAllocatorNull; 252*f4a2713aSLionel Sambucextern const CFAllocatorRef kCFAllocatorUseContext; 253*f4a2713aSLionel SambucCFStringRef CFStringCreateWithBytesNoCopy(CFAllocatorRef alloc, const uint8_t *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean externalFormat, CFAllocatorRef contentsDeallocator); 254*f4a2713aSLionel Sambucextern void CFRelease(CFStringRef cf); 255*f4a2713aSLionel Sambuc 256*f4a2713aSLionel Sambucvoid DellocWithCFStringCreate1(CFAllocatorRef alloc) { 257*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 258*f4a2713aSLionel Sambuc OSStatus st = 0; 259*f4a2713aSLionel Sambuc UInt32 length; 260*f4a2713aSLionel Sambuc void *bytes; 261*f4a2713aSLionel Sambuc char * x; 262*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 263*f4a2713aSLionel Sambuc if (st == noErr) { 264*f4a2713aSLionel Sambuc CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, kCFAllocatorDefault); // expected-warning{{Deallocator doesn't match the allocator:}} 265*f4a2713aSLionel Sambuc CFRelease(userStr); 266*f4a2713aSLionel Sambuc } 267*f4a2713aSLionel Sambuc} 268*f4a2713aSLionel Sambuc 269*f4a2713aSLionel Sambucvoid DellocWithCFStringCreate2(CFAllocatorRef alloc) { 270*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 271*f4a2713aSLionel Sambuc OSStatus st = 0; 272*f4a2713aSLionel Sambuc UInt32 length; 273*f4a2713aSLionel Sambuc void *bytes; 274*f4a2713aSLionel Sambuc char * x; 275*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 276*f4a2713aSLionel Sambuc if (st == noErr) { 277*f4a2713aSLionel Sambuc CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, kCFAllocatorNull); // expected-warning{{Allocated data is not released}} 278*f4a2713aSLionel Sambuc CFRelease(userStr); 279*f4a2713aSLionel Sambuc } 280*f4a2713aSLionel Sambuc} 281*f4a2713aSLionel Sambuc 282*f4a2713aSLionel Sambucvoid DellocWithCFStringCreate3(CFAllocatorRef alloc) { 283*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 284*f4a2713aSLionel Sambuc OSStatus st = 0; 285*f4a2713aSLionel Sambuc UInt32 length; 286*f4a2713aSLionel Sambuc void *bytes; 287*f4a2713aSLionel Sambuc char * x; 288*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 289*f4a2713aSLionel Sambuc if (st == noErr) { 290*f4a2713aSLionel Sambuc CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, kCFAllocatorUseContext); 291*f4a2713aSLionel Sambuc CFRelease(userStr); 292*f4a2713aSLionel Sambuc } 293*f4a2713aSLionel Sambuc} 294*f4a2713aSLionel Sambuc 295*f4a2713aSLionel Sambucvoid DellocWithCFStringCreate4(CFAllocatorRef alloc) { 296*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 297*f4a2713aSLionel Sambuc OSStatus st = 0; 298*f4a2713aSLionel Sambuc UInt32 length; 299*f4a2713aSLionel Sambuc void *bytes; 300*f4a2713aSLionel Sambuc char * x; 301*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 302*f4a2713aSLionel Sambuc if (st == noErr) { 303*f4a2713aSLionel Sambuc CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, 0); // expected-warning{{Deallocator doesn't match the allocator:}} 304*f4a2713aSLionel Sambuc CFRelease(userStr); 305*f4a2713aSLionel Sambuc } 306*f4a2713aSLionel Sambuc} 307*f4a2713aSLionel Sambuc 308*f4a2713aSLionel Sambucstatic CFAllocatorRef gKeychainDeallocator = 0; 309*f4a2713aSLionel Sambuc 310*f4a2713aSLionel Sambucstatic CFAllocatorRef GetKeychainDeallocator() { 311*f4a2713aSLionel Sambuc return gKeychainDeallocator; 312*f4a2713aSLionel Sambuc} 313*f4a2713aSLionel Sambuc 314*f4a2713aSLionel SambucCFStringRef DellocWithCFStringCreate5(CFAllocatorRef alloc) { 315*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 316*f4a2713aSLionel Sambuc OSStatus st = 0; 317*f4a2713aSLionel Sambuc UInt32 length; 318*f4a2713aSLionel Sambuc void *bytes; 319*f4a2713aSLionel Sambuc char * x; 320*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 321*f4a2713aSLionel Sambuc if (st == noErr) { 322*f4a2713aSLionel Sambuc return CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, GetKeychainDeallocator()); // no-warning 323*f4a2713aSLionel Sambuc } 324*f4a2713aSLionel Sambuc return 0; 325*f4a2713aSLionel Sambuc} 326*f4a2713aSLionel Sambuc 327*f4a2713aSLionel Sambucvoid radar10508828() { 328*f4a2713aSLionel Sambuc UInt32 pwdLen = 0; 329*f4a2713aSLionel Sambuc void* pwdBytes = 0; 330*f4a2713aSLionel Sambuc OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0); 331*f4a2713aSLionel Sambuc#pragma unused(rc) 332*f4a2713aSLionel Sambuc if (pwdBytes) 333*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(0, pwdBytes); 334*f4a2713aSLionel Sambuc} 335*f4a2713aSLionel Sambuc 336*f4a2713aSLionel Sambucvoid radar10508828_2() { 337*f4a2713aSLionel Sambuc UInt32 pwdLen = 0; 338*f4a2713aSLionel Sambuc void* pwdBytes = 0; 339*f4a2713aSLionel Sambuc OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0); 340*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(0, pwdBytes); // expected-warning {{Only call free if a valid (non-NULL) buffer was returned}} 341*f4a2713aSLionel Sambuc} 342*f4a2713aSLionel Sambuc 343*f4a2713aSLionel Sambuc//Example from bug 10797. 344*f4a2713aSLionel Sambuc__inline__ static 345*f4a2713aSLionel Sambucconst char *__WBASLLevelString(int level) { 346*f4a2713aSLionel Sambuc return "foo"; 347*f4a2713aSLionel Sambuc} 348*f4a2713aSLionel Sambuc 349*f4a2713aSLionel Sambucstatic int *bug10798(int *p, int columns, int prevRow) { 350*f4a2713aSLionel Sambuc int *row = 0; 351*f4a2713aSLionel Sambuc row = p + prevRow * columns; 352*f4a2713aSLionel Sambuc prevRow += 2; 353*f4a2713aSLionel Sambuc do { 354*f4a2713aSLionel Sambuc ++prevRow; 355*f4a2713aSLionel Sambuc row+=columns; 356*f4a2713aSLionel Sambuc } while(10 >= row[1]); 357*f4a2713aSLionel Sambuc return row; 358*f4a2713aSLionel Sambuc} 359*f4a2713aSLionel Sambuc 360*f4a2713aSLionel Sambuc// Test inter-procedural behaviour. 361*f4a2713aSLionel Sambuc 362*f4a2713aSLionel Sambucvoid my_FreeParam(void *attrList, void* X) { 363*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(attrList, X); 364*f4a2713aSLionel Sambuc} 365*f4a2713aSLionel Sambuc 366*f4a2713aSLionel Sambucvoid *my_AllocateReturn(OSStatus *st) { 367*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 368*f4a2713aSLionel Sambuc UInt32 length; 369*f4a2713aSLionel Sambuc void *outData; 370*f4a2713aSLionel Sambuc *st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 371*f4a2713aSLionel Sambuc return outData; 372*f4a2713aSLionel Sambuc} 373*f4a2713aSLionel Sambuc 374*f4a2713aSLionel SambucOSStatus my_Allocate_Param(void** password, UInt32* passwordLength) { 375*f4a2713aSLionel Sambuc OSStatus err; 376*f4a2713aSLionel Sambuc SecKeychainItemRef item; 377*f4a2713aSLionel Sambuc err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx", 378*f4a2713aSLionel Sambuc passwordLength, password, &item); 379*f4a2713aSLionel Sambuc return err; 380*f4a2713aSLionel Sambuc} 381*f4a2713aSLionel Sambuc 382*f4a2713aSLionel Sambucvoid allocAndFree1() { 383*f4a2713aSLionel Sambuc unsigned int *ptr = 0; 384*f4a2713aSLionel Sambuc OSStatus st = 0; 385*f4a2713aSLionel Sambuc UInt32 length; 386*f4a2713aSLionel Sambuc void *outData; 387*f4a2713aSLionel Sambuc st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 388*f4a2713aSLionel Sambuc if (st == noErr) 389*f4a2713aSLionel Sambuc my_FreeParam(ptr, outData); 390*f4a2713aSLionel Sambuc} 391*f4a2713aSLionel Sambuc 392*f4a2713aSLionel Sambucvoid consumeChar(char); 393*f4a2713aSLionel Sambuc 394*f4a2713aSLionel Sambucvoid allocNoFree2(int x) { 395*f4a2713aSLionel Sambuc OSStatus st = 0; 396*f4a2713aSLionel Sambuc void *outData = my_AllocateReturn(&st); 397*f4a2713aSLionel Sambuc if (x) { 398*f4a2713aSLionel Sambuc consumeChar(*(char*)outData); // expected-warning{{Allocated data is not released:}} 399*f4a2713aSLionel Sambuc return; 400*f4a2713aSLionel Sambuc } else { 401*f4a2713aSLionel Sambuc consumeChar(*(char*)outData); 402*f4a2713aSLionel Sambuc } 403*f4a2713aSLionel Sambuc return; 404*f4a2713aSLionel Sambuc} 405*f4a2713aSLionel Sambuc 406*f4a2713aSLionel Sambucvoid allocAndFree2(void *attrList) { 407*f4a2713aSLionel Sambuc OSStatus st = 0; 408*f4a2713aSLionel Sambuc void *outData = my_AllocateReturn(&st); 409*f4a2713aSLionel Sambuc if (st == noErr) 410*f4a2713aSLionel Sambuc my_FreeParam(attrList, outData); 411*f4a2713aSLionel Sambuc} 412*f4a2713aSLionel Sambuc 413*f4a2713aSLionel Sambucvoid allocNoFree3() { 414*f4a2713aSLionel Sambuc UInt32 length = 32; 415*f4a2713aSLionel Sambuc void *outData; 416*f4a2713aSLionel Sambuc void *outData2; 417*f4a2713aSLionel Sambuc OSStatus st = my_Allocate_Param(&outData, &length); // expected-warning{{Allocated data is not released}} 418*f4a2713aSLionel Sambuc st = my_Allocate_Param(&outData2, &length); // expected-warning{{Allocated data is not released}} 419*f4a2713aSLionel Sambuc} 420*f4a2713aSLionel Sambuc 421*f4a2713aSLionel Sambucvoid allocAndFree3(void *attrList) { 422*f4a2713aSLionel Sambuc UInt32 length = 32; 423*f4a2713aSLionel Sambuc void *outData; 424*f4a2713aSLionel Sambuc OSStatus st = my_Allocate_Param(&outData, &length); 425*f4a2713aSLionel Sambuc if (st == noErr) 426*f4a2713aSLionel Sambuc SecKeychainItemFreeContent(attrList, outData); 427*f4a2713aSLionel Sambuc} 428*f4a2713aSLionel Sambuc 429