keychainAPI.m revision 03826aaf95018e3b29f94a10ca5616c0fc9bbee5
1// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.osx.KeychainAPI %s -verify
2
3// Fake typedefs.
4typedef unsigned int OSStatus;
5typedef unsigned int SecKeychainAttributeList;
6typedef unsigned int SecKeychainItemRef;
7typedef unsigned int SecItemClass;
8typedef unsigned int UInt32;
9typedef unsigned int CFTypeRef;
10typedef unsigned int UInt16;
11typedef unsigned int SecProtocolType;
12typedef unsigned int SecAuthenticationType;
13enum {
14  noErr                      = 0,
15  GenericError               = 1
16};
17
18// Functions that allocate data.
19OSStatus SecKeychainItemCopyContent (
20    SecKeychainItemRef itemRef,
21    SecItemClass *itemClass,
22    SecKeychainAttributeList *attrList,
23    UInt32 *length,
24    void **outData
25);
26OSStatus SecKeychainFindGenericPassword (
27    CFTypeRef keychainOrArray,
28    UInt32 serviceNameLength,
29    const char *serviceName,
30    UInt32 accountNameLength,
31    const char *accountName,
32    UInt32 *passwordLength,
33    void **passwordData,
34    SecKeychainItemRef *itemRef
35);
36OSStatus SecKeychainFindInternetPassword (
37    CFTypeRef keychainOrArray,
38    UInt32 serverNameLength,
39    const char *serverName,
40    UInt32 securityDomainLength,
41    const char *securityDomain,
42    UInt32 accountNameLength,
43    const char *accountName,
44    UInt32 pathLength,
45    const char *path,
46    UInt16 port,
47    SecProtocolType protocol,
48    SecAuthenticationType authenticationType,
49    UInt32 *passwordLength,
50    void **passwordData,
51    SecKeychainItemRef *itemRef
52);
53
54// Function which frees data.
55OSStatus SecKeychainItemFreeContent (
56    SecKeychainAttributeList *attrList,
57    void *data
58);
59
60void errRetVal() {
61	unsigned int *ptr = 0;
62	OSStatus st = 0;
63	UInt32 length;
64	void *outData;
65	st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
66	if (st == GenericError) // expected-warning{{Missing a call to SecKeychainItemFreeContent}}
67		SecKeychainItemFreeContent(ptr, outData);
68}
69
70// If null is passed in, the data is not allocated, so no need for the matching free.
71void fooDoNotReportNull() {
72    unsigned int *ptr = 0;
73    OSStatus st = 0;
74    UInt32 *length = 0;
75    void **outData = 0;
76    SecKeychainItemCopyContent(2, ptr, ptr, 0, 0);
77    SecKeychainItemCopyContent(2, ptr, ptr, length, outData);
78}// no-warning
79
80void fooOnlyFree() {
81  unsigned int *ptr = 0;
82  OSStatus st = 0;
83  UInt32 length;
84  void *outData = &length;
85  SecKeychainItemFreeContent(ptr, outData);// expected-warning{{Trying to free data which has not been allocated}}
86}
87
88// Do not warn if undefined value is passed to a function.
89void fooOnlyFreeUndef() {
90  unsigned int *ptr = 0;
91  OSStatus st = 0;
92  UInt32 length;
93  void *outData;
94  SecKeychainItemFreeContent(ptr, outData);
95}// no-warning
96
97// Do not warn if the address is a parameter in the enclosing function.
98void fooOnlyFreeParam(void* X) {
99  SecKeychainItemFreeContent(X, X); 
100}// no-warning
101
102// If we are returning the value, no not report.
103void* returnContent() {
104  unsigned int *ptr = 0;
105  OSStatus st = 0;
106  UInt32 length;
107  void *outData;
108  st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
109  return outData;
110} // no-warning
111
112int foo () {
113  unsigned int *ptr = 0;
114  OSStatus st = 0;
115
116  UInt32 length;
117  void *outData;
118
119  st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
120  if (st == noErr)
121    SecKeychainItemFreeContent(ptr, outData);
122
123  return 0;
124}// no-warning
125