1*67e74705SXin Li<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 2*67e74705SXin Li "http://www.w3.org/TR/html4/strict.dtd"> 3*67e74705SXin Li<html> 4*67e74705SXin Li<head> 5*67e74705SXin Li <title>Available Checkers</title> 6*67e74705SXin Li <link type="text/css" rel="stylesheet" href="menu.css"> 7*67e74705SXin Li <link type="text/css" rel="stylesheet" href="content.css"> 8*67e74705SXin Li <script type="text/javascript" src="scripts/menu.js"></script> 9*67e74705SXin Li <script type="text/javascript" src="scripts/expandcollapse.js"></script> 10*67e74705SXin Li <style type="text/css"> 11*67e74705SXin Li tr:first-child { width:20%; } 12*67e74705SXin Li </style> 13*67e74705SXin Li</head> 14*67e74705SXin Li<body onload="initExpandCollapse()"> 15*67e74705SXin Li 16*67e74705SXin Li<div id="page"> 17*67e74705SXin Li<!--#include virtual="menu.html.incl"--> 18*67e74705SXin Li 19*67e74705SXin Li<div id="content"> 20*67e74705SXin Li<h1>Available Checkers</h1> 21*67e74705SXin LiThe analyzer performs checks that are categorized into families or "checkers". The 22*67e74705SXin Lidefault set of checkers covers a variety of checks targeted at finding security 23*67e74705SXin Liand API usage bugs, dead code, and other logic errors. See the 24*67e74705SXin Li<a href = "#default_checkers">Default Checkers</a> list below. In addition to 25*67e74705SXin Lithese, the analyzer contains a number of <a href = "alpha_checks.html"> 26*67e74705SXin LiExperimental (Alpha) Checkers</a>. 27*67e74705SXin Li 28*67e74705SXin Li<h3>Writeups with examples of some of the bugs that the analyzer finds</h3> 29*67e74705SXin Li<ul> 30*67e74705SXin Li<li><a href="http://www.mobileorchard.com/bug-finding-with-clang-5-resources-to-get-you-started/">Bug Finding With Clang: 5 Resources To Get You Started</a></li> 31*67e74705SXin Li<li><a href="http://fruitstandsoftware.com/blog/index.php/2008/08/finding-memory-leaks-with-the-llvmclang-static-analyzer/#comment-2">Finding Memory Leaks With The LLVM/Clang Static Analyzer</a></li> 32*67e74705SXin Li<li><a href="http://www.rogueamoeba.com/utm/2008/07/14/the-clang-static-analyzer/">Under the Microscope - The Clang Static Analyzer</a></li> 33*67e74705SXin Li<li><a href="http://www.mikeash.com/?page=pyblog/friday-qa-2009-03-06-using-the-clang-static-analyzer.html">Mike Ash - Using the Clang Static Analyzer</a></li> 34*67e74705SXin Li</ul> 35*67e74705SXin Li 36*67e74705SXin Li<h2 id="default_checkers">Default Checkers</h2> 37*67e74705SXin Li<ul> 38*67e74705SXin Li<li><a href="#core_checkers">Core Checkers</a> model core language features and perform general-purpose checks such as division by zero, null pointer dereference, usage of uninitialized values, etc.</li> 39*67e74705SXin Li<li><a href="#cplusplus_checkers">C++ Checkers</a> perform C++-specific checks</li> 40*67e74705SXin Li<li><a href="#deadcode_checkers">Dead Code Checkers</a> check for unused code</li> 41*67e74705SXin Li<li><a href="#osx_checkers">OS X Checkers</a> perform Objective-C-specific checks and check the use of Apple's SDKs (OS X and iOS)</li> 42*67e74705SXin Li<li><a href="#security_checkers">Security Checkers</a> check for insecure API usage and perform checks based on the CERT Secure Coding Standards</li> 43*67e74705SXin Li<li><a href="#unix_checkers">Unix Checkers</a> check the use of Unix and POSIX APIs</li> 44*67e74705SXin Li</ul> 45*67e74705SXin Li 46*67e74705SXin Li<!------------------------------------ core -----------------------------------> 47*67e74705SXin Li<h3 id="core_checkers">Core Checkers</h3> 48*67e74705SXin Li<table class="checkers"> 49*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup> 50*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> 51*67e74705SXin Li 52*67e74705SXin Li<tbody> 53*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 54*67e74705SXin Licore.CallAndMessage</span><span class="lang"> 55*67e74705SXin Li(C, C++, ObjC)</span><div class="descr"> 56*67e74705SXin LiCheck for logical errors for function calls and Objective-C message expressions 57*67e74705SXin Li(e.g., uninitialized arguments, null function pointers).</div></div></td> 58*67e74705SXin Li<td><div class="exampleContainer expandable"> 59*67e74705SXin Li<div class="example"><pre> 60*67e74705SXin Li// C 61*67e74705SXin Listruct S { 62*67e74705SXin Li int x; 63*67e74705SXin Li}; 64*67e74705SXin Li 65*67e74705SXin Livoid f(struct S s); 66*67e74705SXin Li 67*67e74705SXin Livoid test() { 68*67e74705SXin Li struct S s; 69*67e74705SXin Li f(s); // warn: passed-by-value arg contain uninitialized data 70*67e74705SXin Li} 71*67e74705SXin Li</pre></div> 72*67e74705SXin Li<div class="example"><pre> 73*67e74705SXin Li// C 74*67e74705SXin Livoid test() { 75*67e74705SXin Li void (*foo)(void); 76*67e74705SXin Li foo(); // warn: function pointer is uninitialized 77*67e74705SXin Li} 78*67e74705SXin Li</pre></div> 79*67e74705SXin Li<div class="example"><pre> 80*67e74705SXin Li// C 81*67e74705SXin Livoid test() { 82*67e74705SXin Li void (*foo)(void); 83*67e74705SXin Li foo = 0; 84*67e74705SXin Li foo(); // warn: function pointer is null 85*67e74705SXin Li} 86*67e74705SXin Li</pre></div> 87*67e74705SXin Li<div class="example"><pre> 88*67e74705SXin Li// C++ 89*67e74705SXin Liclass C { 90*67e74705SXin Lipublic: 91*67e74705SXin Li void f(); 92*67e74705SXin Li}; 93*67e74705SXin Li 94*67e74705SXin Livoid test() { 95*67e74705SXin Li C *pc; 96*67e74705SXin Li pc->f(); // warn: object pointer is uninitialized 97*67e74705SXin Li} 98*67e74705SXin Li</pre></div> 99*67e74705SXin Li<div class="example"><pre> 100*67e74705SXin Li// C++ 101*67e74705SXin Liclass C { 102*67e74705SXin Lipublic: 103*67e74705SXin Li void f(); 104*67e74705SXin Li}; 105*67e74705SXin Li 106*67e74705SXin Livoid test() { 107*67e74705SXin Li C *pc = 0; 108*67e74705SXin Li pc->f(); // warn: object pointer is null 109*67e74705SXin Li} 110*67e74705SXin Li</pre></div> 111*67e74705SXin Li<div class="example"><pre> 112*67e74705SXin Li// Objective-C 113*67e74705SXin Li@interface MyClass : NSObject 114*67e74705SXin Li@property (readwrite,assign) id x; 115*67e74705SXin Li- (long double)longDoubleM; 116*67e74705SXin Li@end 117*67e74705SXin Li 118*67e74705SXin Livoid test() { 119*67e74705SXin Li MyClass *obj1; 120*67e74705SXin Li long double ld1 = [obj1 longDoubleM]; 121*67e74705SXin Li // warn: receiver is uninitialized 122*67e74705SXin Li} 123*67e74705SXin Li</pre></div> 124*67e74705SXin Li<div class="example"><pre> 125*67e74705SXin Li// Objective-C 126*67e74705SXin Li@interface MyClass : NSObject 127*67e74705SXin Li@property (readwrite,assign) id x; 128*67e74705SXin Li- (long double)longDoubleM; 129*67e74705SXin Li@end 130*67e74705SXin Li 131*67e74705SXin Livoid test() { 132*67e74705SXin Li MyClass *obj1; 133*67e74705SXin Li id i = obj1.x; // warn: uninitialized object pointer 134*67e74705SXin Li} 135*67e74705SXin Li</pre></div> 136*67e74705SXin Li<div class="example"><pre> 137*67e74705SXin Li// Objective-C 138*67e74705SXin Li@interface Subscriptable : NSObject 139*67e74705SXin Li- (id)objectAtIndexedSubscript:(unsigned int)index; 140*67e74705SXin Li@end 141*67e74705SXin Li 142*67e74705SXin Li@interface MyClass : Subscriptable 143*67e74705SXin Li@property (readwrite,assign) id x; 144*67e74705SXin Li- (long double)longDoubleM; 145*67e74705SXin Li@end 146*67e74705SXin Li 147*67e74705SXin Livoid test() { 148*67e74705SXin Li MyClass *obj1; 149*67e74705SXin Li id i = obj1[0]; // warn: uninitialized object pointer 150*67e74705SXin Li} 151*67e74705SXin Li</pre></div></div></td></tr> 152*67e74705SXin Li 153*67e74705SXin Li 154*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 155*67e74705SXin Licore.DivideZero</span><span class="lang"> 156*67e74705SXin Li(C, C++, ObjC)</span><div class="descr"> 157*67e74705SXin LiCheck for division by zero.</div></div></td> 158*67e74705SXin Li<td><div class="exampleContainer expandable"> 159*67e74705SXin Li<div class="example"><pre> 160*67e74705SXin Livoid test(int z) { 161*67e74705SXin Li if (z == 0) 162*67e74705SXin Li int x = 1 / z; // warn 163*67e74705SXin Li} 164*67e74705SXin Li</pre></div> 165*67e74705SXin Li<div class="example"><pre> 166*67e74705SXin Livoid test() { 167*67e74705SXin Li int x = 1; 168*67e74705SXin Li int y = x % 0; // warn 169*67e74705SXin Li} 170*67e74705SXin Li</pre></div></div></td></tr> 171*67e74705SXin Li 172*67e74705SXin Li 173*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 174*67e74705SXin Licore.NonNullParamChecker</span><span class="lang"> 175*67e74705SXin Li(C, C++, ObjC)</span><div class="descr"> 176*67e74705SXin LiCheck for null pointers passed as arguments to a function whose arguments are 177*67e74705SXin Limarked with the <code>nonnull</code> attribute.</div></div></td> 178*67e74705SXin Li<td><div class="exampleContainer expandable"> 179*67e74705SXin Li<div class="example"><pre> 180*67e74705SXin Liint f(int *p) __attribute__((nonnull)); 181*67e74705SXin Li 182*67e74705SXin Livoid test(int *p) { 183*67e74705SXin Li if (!p) 184*67e74705SXin Li f(p); // warn 185*67e74705SXin Li} 186*67e74705SXin Li</pre></div></div></td></tr> 187*67e74705SXin Li 188*67e74705SXin Li 189*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 190*67e74705SXin Licore.NullDereference</span><span class="lang"> 191*67e74705SXin Li(C, C++, ObjC)</span><div class="descr"> 192*67e74705SXin LiCheck for dereferences of null pointers.</div></div></td> 193*67e74705SXin Li<td><div class="exampleContainer expandable"> 194*67e74705SXin Li<div class="example"><pre> 195*67e74705SXin Li// C 196*67e74705SXin Livoid test(int *p) { 197*67e74705SXin Li if (p) 198*67e74705SXin Li return; 199*67e74705SXin Li 200*67e74705SXin Li int x = p[0]; // warn 201*67e74705SXin Li} 202*67e74705SXin Li</pre></div> 203*67e74705SXin Li<div class="example"><pre> 204*67e74705SXin Li// C 205*67e74705SXin Livoid test(int *p) { 206*67e74705SXin Li if (!p) 207*67e74705SXin Li *p = 0; // warn 208*67e74705SXin Li} 209*67e74705SXin Li</pre></div> 210*67e74705SXin Li<div class="example"><pre> 211*67e74705SXin Li// C++ 212*67e74705SXin Liclass C { 213*67e74705SXin Lipublic: 214*67e74705SXin Li int x; 215*67e74705SXin Li}; 216*67e74705SXin Li 217*67e74705SXin Livoid test() { 218*67e74705SXin Li C *pc = 0; 219*67e74705SXin Li int k = pc->x; // warn 220*67e74705SXin Li} 221*67e74705SXin Li</pre></div> 222*67e74705SXin Li<div class="example"><pre> 223*67e74705SXin Li// Objective-C 224*67e74705SXin Li@interface MyClass { 225*67e74705SXin Li@public 226*67e74705SXin Li int x; 227*67e74705SXin Li} 228*67e74705SXin Li@end 229*67e74705SXin Li 230*67e74705SXin Livoid test() { 231*67e74705SXin Li MyClass *obj = 0; 232*67e74705SXin Li obj->x = 1; // warn 233*67e74705SXin Li} 234*67e74705SXin Li</pre></div></div></td></tr> 235*67e74705SXin Li 236*67e74705SXin Li 237*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 238*67e74705SXin Licore.StackAddressEscape</span><span class="lang"> 239*67e74705SXin Li(C)</span><div class="descr"> 240*67e74705SXin LiCheck that addresses of stack memory do not escape the function.</div></div></td> 241*67e74705SXin Li<td><div class="exampleContainer expandable"> 242*67e74705SXin Li<div class="example"><pre> 243*67e74705SXin Lichar const *p; 244*67e74705SXin Li 245*67e74705SXin Livoid test() { 246*67e74705SXin Li char const str[] = "string"; 247*67e74705SXin Li p = str; // warn 248*67e74705SXin Li} 249*67e74705SXin Li</pre></div> 250*67e74705SXin Li<div class="example"><pre> 251*67e74705SXin Livoid* test() { 252*67e74705SXin Li return __builtin_alloca(12); // warn 253*67e74705SXin Li} 254*67e74705SXin Li</pre></div> 255*67e74705SXin Li<div class="example"><pre> 256*67e74705SXin Livoid test() { 257*67e74705SXin Li static int *x; 258*67e74705SXin Li int y; 259*67e74705SXin Li x = &y; // warn 260*67e74705SXin Li} 261*67e74705SXin Li</pre></div></div></td></tr> 262*67e74705SXin Li 263*67e74705SXin Li 264*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 265*67e74705SXin Licore.UndefinedBinaryOperatorResult</span><span class="lang"> 266*67e74705SXin Li(C)</span><div class="descr"> 267*67e74705SXin LiCheck for undefined results of binary operators.</div></div></td> 268*67e74705SXin Li<td><div class="exampleContainer expandable"> 269*67e74705SXin Li<div class="example"><pre> 270*67e74705SXin Livoid test() { 271*67e74705SXin Li int x; 272*67e74705SXin Li int y = x + 1; // warn: left operand is garbage 273*67e74705SXin Li} 274*67e74705SXin Li</pre></div></div></td></tr> 275*67e74705SXin Li 276*67e74705SXin Li 277*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 278*67e74705SXin Licore.VLASize</span><span class="lang"> 279*67e74705SXin Li(C)</span><div class="descr"> 280*67e74705SXin LiCheck for declarations of VLA of undefined or zero size.</div></div></td> 281*67e74705SXin Li<td><div class="exampleContainer expandable"> 282*67e74705SXin Li<div class="example"><pre> 283*67e74705SXin Livoid test() { 284*67e74705SXin Li int x; 285*67e74705SXin Li int vla1[x]; // warn: garbage as size 286*67e74705SXin Li} 287*67e74705SXin Li</pre></div> 288*67e74705SXin Li<div class="example"><pre> 289*67e74705SXin Livoid test() { 290*67e74705SXin Li int x = 0; 291*67e74705SXin Li int vla2[x]; // warn: zero size 292*67e74705SXin Li} 293*67e74705SXin Li</pre></div></div></td></tr> 294*67e74705SXin Li 295*67e74705SXin Li 296*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 297*67e74705SXin Licore.uninitialized.ArraySubscript</span><span class="lang"> 298*67e74705SXin Li(C)</span><div class="descr"> 299*67e74705SXin LiCheck for uninitialized values used as array subscripts.</div></div></td> 300*67e74705SXin Li<td><div class="exampleContainer expandable"> 301*67e74705SXin Li<div class="example"><pre> 302*67e74705SXin Livoid test() { 303*67e74705SXin Li int i, a[10]; 304*67e74705SXin Li int x = a[i]; // warn: array subscript is undefined 305*67e74705SXin Li} 306*67e74705SXin Li</pre></div></div></td></tr> 307*67e74705SXin Li 308*67e74705SXin Li 309*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 310*67e74705SXin Licore.uninitialized.Assign</span><span class="lang"> 311*67e74705SXin Li(C)</span><div class="descr"> 312*67e74705SXin LiCheck for assigning uninitialized values.</div></div></td> 313*67e74705SXin Li<td><div class="exampleContainer expandable"> 314*67e74705SXin Li<div class="example"><pre> 315*67e74705SXin Livoid test() { 316*67e74705SXin Li int x; 317*67e74705SXin Li x |= 1; // warn: left expression is unitialized 318*67e74705SXin Li} 319*67e74705SXin Li</pre></div></div></td></tr> 320*67e74705SXin Li 321*67e74705SXin Li 322*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 323*67e74705SXin Licore.uninitialized.Branch</span><span class="lang"> 324*67e74705SXin Li(C)</span><div class="descr"> 325*67e74705SXin LiCheck for uninitialized values used as branch conditions.</div></div></td> 326*67e74705SXin Li<td><div class="exampleContainer expandable"> 327*67e74705SXin Li<div class="example"><pre> 328*67e74705SXin Livoid test() { 329*67e74705SXin Li int x; 330*67e74705SXin Li if (x) // warn 331*67e74705SXin Li return; 332*67e74705SXin Li} 333*67e74705SXin Li</pre></div></div></td></tr> 334*67e74705SXin Li 335*67e74705SXin Li 336*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 337*67e74705SXin Licore.uninitialized.CapturedBlockVariable</span><span class="lang"> 338*67e74705SXin Li(C)</span><div class="descr"> 339*67e74705SXin LiCheck for blocks that capture uninitialized values.</div></div></td> 340*67e74705SXin Li<td><div class="exampleContainer expandable"> 341*67e74705SXin Li<div class="example"><pre> 342*67e74705SXin Livoid test() { 343*67e74705SXin Li int x; 344*67e74705SXin Li ^{ int y = x; }(); // warn 345*67e74705SXin Li} 346*67e74705SXin Li</pre></div></div></td></tr> 347*67e74705SXin Li 348*67e74705SXin Li 349*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 350*67e74705SXin Licore.uninitialized.UndefReturn</span><span class="lang"> 351*67e74705SXin Li(C)</span><div class="descr"> 352*67e74705SXin LiCheck for uninitialized values being returned to the caller.</div></div></td> 353*67e74705SXin Li<td><div class="exampleContainer expandable"> 354*67e74705SXin Li<div class="example"><pre> 355*67e74705SXin Liint test() { 356*67e74705SXin Li int x; 357*67e74705SXin Li return x; // warn 358*67e74705SXin Li} 359*67e74705SXin Li</pre></div></div></td></tr> 360*67e74705SXin Li 361*67e74705SXin Li</tbody></table> 362*67e74705SXin Li 363*67e74705SXin Li<!------------------------------------ C++ ------------------------------------> 364*67e74705SXin Li<h3 id="cplusplus_checkers">C++ Checkers</h3> 365*67e74705SXin Li<table class="checkers"> 366*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup> 367*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> 368*67e74705SXin Li 369*67e74705SXin Li<tbody> 370*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 371*67e74705SXin Licplusplus.NewDelete</span><span class="lang"> 372*67e74705SXin Li(C++)</span><div class="descr"> 373*67e74705SXin LiCheck for double-free, use-after-free and offset problems involving C++ <code> 374*67e74705SXin Lidelete</code>.</div></div></td> 375*67e74705SXin Li<td><div class="exampleContainer expandable"> 376*67e74705SXin Li<div class="example"><pre> 377*67e74705SXin Livoid f(int *p); 378*67e74705SXin Li 379*67e74705SXin Livoid testUseMiddleArgAfterDelete(int *p) { 380*67e74705SXin Li delete p; 381*67e74705SXin Li f(p); // warn: use after free 382*67e74705SXin Li} 383*67e74705SXin Li</pre></div> 384*67e74705SXin Li<div class="example"><pre> 385*67e74705SXin Liclass SomeClass { 386*67e74705SXin Lipublic: 387*67e74705SXin Li void f(); 388*67e74705SXin Li}; 389*67e74705SXin Li 390*67e74705SXin Livoid test() { 391*67e74705SXin Li SomeClass *c = new SomeClass; 392*67e74705SXin Li delete c; 393*67e74705SXin Li c->f(); // warn: use after free 394*67e74705SXin Li} 395*67e74705SXin Li</pre></div> 396*67e74705SXin Li<div class="example"><pre> 397*67e74705SXin Livoid test() { 398*67e74705SXin Li int *p = (int *)__builtin_alloca(sizeof(int)); 399*67e74705SXin Li delete p; // warn: deleting memory allocated by alloca 400*67e74705SXin Li} 401*67e74705SXin Li</pre></div> 402*67e74705SXin Li<div class="example"><pre> 403*67e74705SXin Livoid test() { 404*67e74705SXin Li int *p = new int; 405*67e74705SXin Li delete p; 406*67e74705SXin Li delete p; // warn: attempt to free released 407*67e74705SXin Li} 408*67e74705SXin Li</pre></div> 409*67e74705SXin Li<div class="example"><pre> 410*67e74705SXin Livoid test() { 411*67e74705SXin Li int i; 412*67e74705SXin Li delete &i; // warn: delete address of local 413*67e74705SXin Li} 414*67e74705SXin Li</pre></div> 415*67e74705SXin Li<div class="example"><pre> 416*67e74705SXin Livoid test() { 417*67e74705SXin Li int *p = new int[1]; 418*67e74705SXin Li delete[] (++p); 419*67e74705SXin Li // warn: argument to 'delete[]' is offset by 4 bytes 420*67e74705SXin Li // from the start of memory allocated by 'new[]' 421*67e74705SXin Li} 422*67e74705SXin Li</pre></div></div></td></tr> 423*67e74705SXin Li 424*67e74705SXin Li</tbody></table> 425*67e74705SXin Li 426*67e74705SXin Li<!--------------------------------- dead code ---------------------------------> 427*67e74705SXin Li<h3 id="deadcode_checkers">Dead Code Checkers</h3> 428*67e74705SXin Li<table class="checkers"> 429*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup> 430*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> 431*67e74705SXin Li 432*67e74705SXin Li<tbody> 433*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 434*67e74705SXin Lideadcode.DeadStores</span><span class="lang"> 435*67e74705SXin Li(C)</span><div class="descr"> 436*67e74705SXin LiCheck for values stored to variables that are never read afterwards.</div></div></td> 437*67e74705SXin Li<td><div class="exampleContainer expandable"> 438*67e74705SXin Li<div class="example"><pre> 439*67e74705SXin Livoid test() { 440*67e74705SXin Li int x; 441*67e74705SXin Li x = 1; // warn 442*67e74705SXin Li} 443*67e74705SXin Li</pre></div></div></td></tr> 444*67e74705SXin Li 445*67e74705SXin Li</tbody></table> 446*67e74705SXin Li 447*67e74705SXin Li<!---------------------------------- OS X ------------------------------------> 448*67e74705SXin Li<h3 id="osx_checkers">OS X Checkers</h3> 449*67e74705SXin Li<table class="checkers"> 450*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup> 451*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> 452*67e74705SXin Li 453*67e74705SXin Li<tbody> 454*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 455*67e74705SXin Liosx.API</span><span class="lang"> 456*67e74705SXin Li(C)</span><div class="descr"> 457*67e74705SXin LiCheck for proper uses of various Apple APIs:<div class=functions> 458*67e74705SXin Lidispatch_once</div></div></div></td> 459*67e74705SXin Li<td><div class="exampleContainer expandable"> 460*67e74705SXin Li<div class="example"><pre> 461*67e74705SXin Livoid test() { 462*67e74705SXin Li dispatch_once_t pred = 0; 463*67e74705SXin Li dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local 464*67e74705SXin Li} 465*67e74705SXin Li</pre></div></div></td></tr> 466*67e74705SXin Li 467*67e74705SXin Li 468*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 469*67e74705SXin Liosx.SecKeychainAPI</span><span class="lang"> 470*67e74705SXin Li(C)</span><div class="descr"> 471*67e74705SXin LiCheck for improper uses of the Security framework's Keychain APIs:<div class=functions> 472*67e74705SXin LiSecKeychainItemCopyContent<br> 473*67e74705SXin LiSecKeychainFindGenericPassword<br> 474*67e74705SXin LiSecKeychainFindInternetPassword<br> 475*67e74705SXin LiSecKeychainItemFreeContent<br> 476*67e74705SXin LiSecKeychainItemCopyAttributesAndData<br> 477*67e74705SXin LiSecKeychainItemFreeAttributesAndData</div></div></div></td> 478*67e74705SXin Li<td><div class="exampleContainer expandable"> 479*67e74705SXin Li<div class="example"><pre> 480*67e74705SXin Livoid test() { 481*67e74705SXin Li unsigned int *ptr = 0; 482*67e74705SXin Li UInt32 length; 483*67e74705SXin Li 484*67e74705SXin Li SecKeychainItemFreeContent(ptr, &length); 485*67e74705SXin Li // warn: trying to free data which has not been allocated 486*67e74705SXin Li} 487*67e74705SXin Li</pre></div> 488*67e74705SXin Li<div class="example"><pre> 489*67e74705SXin Livoid test() { 490*67e74705SXin Li unsigned int *ptr = 0; 491*67e74705SXin Li UInt32 *length = 0; 492*67e74705SXin Li void *outData; 493*67e74705SXin Li 494*67e74705SXin Li OSStatus st = 495*67e74705SXin Li SecKeychainItemCopyContent(2, ptr, ptr, length, outData); 496*67e74705SXin Li // warn: data is not released 497*67e74705SXin Li} 498*67e74705SXin Li</pre></div> 499*67e74705SXin Li<div class="example"><pre> 500*67e74705SXin Livoid test() { 501*67e74705SXin Li unsigned int *ptr = 0; 502*67e74705SXin Li UInt32 *length = 0; 503*67e74705SXin Li void *outData; 504*67e74705SXin Li 505*67e74705SXin Li OSStatus st = 506*67e74705SXin Li SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); 507*67e74705SXin Li 508*67e74705SXin Li SecKeychainItemFreeContent(ptr, outData); 509*67e74705SXin Li // warn: only call free if a non-NULL buffer was returned 510*67e74705SXin Li} 511*67e74705SXin Li</pre></div> 512*67e74705SXin Li<div class="example"><pre> 513*67e74705SXin Livoid test() { 514*67e74705SXin Li unsigned int *ptr = 0; 515*67e74705SXin Li UInt32 *length = 0; 516*67e74705SXin Li void *outData; 517*67e74705SXin Li 518*67e74705SXin Li OSStatus st = 519*67e74705SXin Li SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); 520*67e74705SXin Li 521*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); 522*67e74705SXin Li // warn: release data before another call to the allocator 523*67e74705SXin Li 524*67e74705SXin Li if (st == noErr) 525*67e74705SXin Li SecKeychainItemFreeContent(ptr, outData); 526*67e74705SXin Li} 527*67e74705SXin Li</pre></div> 528*67e74705SXin Li<div class="example"><pre> 529*67e74705SXin Livoid test() { 530*67e74705SXin Li SecKeychainItemRef itemRef = 0; 531*67e74705SXin Li SecKeychainAttributeInfo *info = 0; 532*67e74705SXin Li SecItemClass *itemClass = 0; 533*67e74705SXin Li SecKeychainAttributeList *attrList = 0; 534*67e74705SXin Li UInt32 *length = 0; 535*67e74705SXin Li void *outData = 0; 536*67e74705SXin Li 537*67e74705SXin Li OSStatus st = 538*67e74705SXin Li SecKeychainItemCopyAttributesAndData(itemRef, info, 539*67e74705SXin Li itemClass, &attrList, 540*67e74705SXin Li length, &outData); 541*67e74705SXin Li 542*67e74705SXin Li SecKeychainItemFreeContent(attrList, outData); 543*67e74705SXin Li // warn: deallocator doesn't match the allocator 544*67e74705SXin Li} 545*67e74705SXin Li</pre></div></div></td></tr> 546*67e74705SXin Li 547*67e74705SXin Li 548*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 549*67e74705SXin Liosx.cocoa.AtSync</span><span class="lang"> 550*67e74705SXin Li(ObjC)</span><div class="descr"> 551*67e74705SXin LiCheck for nil pointers used as mutexes for <code>@synchronized</code>.</div></div></td> 552*67e74705SXin Li<td><div class="exampleContainer expandable"> 553*67e74705SXin Li<div class="example"><pre> 554*67e74705SXin Livoid test(id x) { 555*67e74705SXin Li if (!x) 556*67e74705SXin Li @synchronized(x) {} // warn: nil value used as mutex 557*67e74705SXin Li} 558*67e74705SXin Li</pre></div> 559*67e74705SXin Li<div class="example"><pre> 560*67e74705SXin Livoid test() { 561*67e74705SXin Li id y; 562*67e74705SXin Li @synchronized(y) {} // warn: uninitialized value used as mutex 563*67e74705SXin Li} 564*67e74705SXin Li</pre></div></div></td></tr> 565*67e74705SXin Li 566*67e74705SXin Li 567*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 568*67e74705SXin Liosx.cocoa.ClassRelease</span><span class="lang"> 569*67e74705SXin Li(ObjC)</span><div class="descr"> 570*67e74705SXin LiCheck for sending <code>retain</code>, <code>release</code>, or <code> 571*67e74705SXin Liautorelease</code> directly to a class.</div></div></td> 572*67e74705SXin Li<td><div class="exampleContainer expandable"> 573*67e74705SXin Li<div class="example"><pre> 574*67e74705SXin Li@interface MyClass : NSObject 575*67e74705SXin Li@end 576*67e74705SXin Li 577*67e74705SXin Livoid test(void) { 578*67e74705SXin Li [MyClass release]; // warn 579*67e74705SXin Li} 580*67e74705SXin Li</pre></div></div></td></tr> 581*67e74705SXin Li 582*67e74705SXin Li 583*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 584*67e74705SXin Liosx.cocoa.IncompatibleMethodTypes</span><span class="lang"> 585*67e74705SXin Li(ObjC)</span><div class="descr"> 586*67e74705SXin LiCheck for an incompatible type signature when overriding an Objective-C method.</div></div></td> 587*67e74705SXin Li<td><div class="exampleContainer expandable"> 588*67e74705SXin Li<div class="example"><pre> 589*67e74705SXin Li@interface MyClass1 : NSObject 590*67e74705SXin Li- (int)foo; 591*67e74705SXin Li@end 592*67e74705SXin Li 593*67e74705SXin Li@implementation MyClass1 594*67e74705SXin Li- (int)foo { return 1; } 595*67e74705SXin Li@end 596*67e74705SXin Li 597*67e74705SXin Li@interface MyClass2 : MyClass1 598*67e74705SXin Li- (float)foo; 599*67e74705SXin Li@end 600*67e74705SXin Li 601*67e74705SXin Li@implementation MyClass2 602*67e74705SXin Li- (float)foo { return 1.0; } // warn 603*67e74705SXin Li@end 604*67e74705SXin Li</pre></div></div></td></tr> 605*67e74705SXin Li 606*67e74705SXin Li 607*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 608*67e74705SXin Lialpha.osx.cocoa.MissingSuperCall</span><span class="lang"> 609*67e74705SXin Li(ObjC)</span><div class="descr"> 610*67e74705SXin LiWarn about Objective-C methods that lack a necessary call to super. (Note: The 611*67e74705SXin Licompiler now has a warning for methods annotated with <code>objc_requires_super</code> 612*67e74705SXin Liattribute. The checker exists to check methods in the Cocoa frameworks 613*67e74705SXin Lithat haven't yet adopted this attribute.)</div></div></td> 614*67e74705SXin Li<td><div class="example"><pre> 615*67e74705SXin Li@interface Test : UIViewController 616*67e74705SXin Li@end 617*67e74705SXin Li@implementation test 618*67e74705SXin Li- (void)viewDidLoad {} // warn 619*67e74705SXin Li@end 620*67e74705SXin Li</pre></div></td></tr> 621*67e74705SXin Li 622*67e74705SXin Li 623*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 624*67e74705SXin Liosx.cocoa.NSAutoreleasePool</span><span class="lang"> 625*67e74705SXin Li(ObjC)</span><div class="descr"> 626*67e74705SXin LiWarn for suboptimal uses of NSAutoreleasePool in Objective-C 627*67e74705SXin LiGC mode (<code>-fobjc-gc</code> compiler option).</div></div></td> 628*67e74705SXin Li<td><div class="exampleContainer expandable"> 629*67e74705SXin Li<div class="example"><pre> 630*67e74705SXin Livoid test() { 631*67e74705SXin Li NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 632*67e74705SXin Li [pool release]; // warn 633*67e74705SXin Li} 634*67e74705SXin Li</pre></div></div></td></tr> 635*67e74705SXin Li 636*67e74705SXin Li 637*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 638*67e74705SXin Liosx.cocoa.NSError</span><span class="lang"> 639*67e74705SXin Li(ObjC)</span><div class="descr"> 640*67e74705SXin LiCheck usage of <code>NSError**</code> parameters.</div></div></td> 641*67e74705SXin Li<td><div class="exampleContainer expandable"> 642*67e74705SXin Li<div class="example"><pre> 643*67e74705SXin Li@interface A : NSObject 644*67e74705SXin Li- (void)foo:(NSError **)error; 645*67e74705SXin Li@end 646*67e74705SXin Li 647*67e74705SXin Li@implementation A 648*67e74705SXin Li- (void)foo:(NSError **)error { 649*67e74705SXin Li // warn: method accepting NSError** should have a non-void 650*67e74705SXin Li // return value 651*67e74705SXin Li} 652*67e74705SXin Li@end 653*67e74705SXin Li</pre></div> 654*67e74705SXin Li<div class="example"><pre> 655*67e74705SXin Li@interface A : NSObject 656*67e74705SXin Li- (BOOL)foo:(NSError **)error; 657*67e74705SXin Li@end 658*67e74705SXin Li 659*67e74705SXin Li@implementation A 660*67e74705SXin Li- (BOOL)foo:(NSError **)error { 661*67e74705SXin Li *error = 0; // warn: potential null dereference 662*67e74705SXin Li return 0; 663*67e74705SXin Li} 664*67e74705SXin Li@end 665*67e74705SXin Li</pre></div></div></td></tr> 666*67e74705SXin Li 667*67e74705SXin Li 668*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 669*67e74705SXin Liosx.cocoa.NilArg</span><span class="lang"> 670*67e74705SXin Li(ObjC)</span><div class="descr"> 671*67e74705SXin LiCheck for prohibited nil arguments in specific Objective-C method calls:<div class=functions> 672*67e74705SXin Li- caseInsensitiveCompare:<br> 673*67e74705SXin Li- compare:<br> 674*67e74705SXin Li- compare:options:<br> 675*67e74705SXin Li- compare:options:range:<br> 676*67e74705SXin Li- compare:options:range:locale:<br> 677*67e74705SXin Li- componentsSeparatedByCharactersInSet:<br> 678*67e74705SXin Li- initWithFormat:</div></div></div></td> 679*67e74705SXin Li<td><div class="exampleContainer expandable"> 680*67e74705SXin Li<div class="example"><pre> 681*67e74705SXin LiNSComparisonResult test(NSString *s) { 682*67e74705SXin Li NSString *aString = nil; 683*67e74705SXin Li return [s caseInsensitiveCompare:aString]; 684*67e74705SXin Li // warn: argument to 'NSString' method 685*67e74705SXin Li // 'caseInsensitiveCompare:' cannot be nil 686*67e74705SXin Li} 687*67e74705SXin Li</pre></div></div></td></tr> 688*67e74705SXin Li 689*67e74705SXin Li 690*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 691*67e74705SXin Liosx.cocoa.RetainCount</span><span class="lang"> 692*67e74705SXin Li(ObjC)</span><div class="descr"> 693*67e74705SXin LiCheck for leaks and violations of the Cocoa Memory Management rules.</div></div></td> 694*67e74705SXin Li<td><div class="exampleContainer expandable"> 695*67e74705SXin Li<div class="example"><pre> 696*67e74705SXin Livoid test() { 697*67e74705SXin Li NSString *s = [[NSString alloc] init]; // warn 698*67e74705SXin Li} 699*67e74705SXin Li</pre></div> 700*67e74705SXin Li<div class="example"><pre> 701*67e74705SXin LiCFStringRef test(char *bytes) { 702*67e74705SXin Li return CFStringCreateWithCStringNoCopy( 703*67e74705SXin Li 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn 704*67e74705SXin Li} 705*67e74705SXin Li</pre></div></div></td></tr> 706*67e74705SXin Li 707*67e74705SXin Li 708*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 709*67e74705SXin Liosx.cocoa.SelfInit</span><span class="lang"> 710*67e74705SXin Li(ObjC)</span><div class="descr"> 711*67e74705SXin LiCheck that <code>self</code> is properly initialized inside an initializer 712*67e74705SXin Limethod.</div></div></td> 713*67e74705SXin Li<td><div class="exampleContainer expandable"> 714*67e74705SXin Li<div class="example"><pre> 715*67e74705SXin Li@interface MyObj : NSObject { 716*67e74705SXin Li id x; 717*67e74705SXin Li} 718*67e74705SXin Li- (id)init; 719*67e74705SXin Li@end 720*67e74705SXin Li 721*67e74705SXin Li@implementation MyObj 722*67e74705SXin Li- (id)init { 723*67e74705SXin Li [super init]; 724*67e74705SXin Li x = 0; // warn: instance variable used while 'self' is not 725*67e74705SXin Li // initialized 726*67e74705SXin Li return 0; 727*67e74705SXin Li} 728*67e74705SXin Li@end 729*67e74705SXin Li</pre></div> 730*67e74705SXin Li<div class="example"><pre> 731*67e74705SXin Li@interface MyObj : NSObject 732*67e74705SXin Li- (id)init; 733*67e74705SXin Li@end 734*67e74705SXin Li 735*67e74705SXin Li@implementation MyObj 736*67e74705SXin Li- (id)init { 737*67e74705SXin Li [super init]; 738*67e74705SXin Li return self; // warn: returning uninitialized 'self' 739*67e74705SXin Li} 740*67e74705SXin Li@end 741*67e74705SXin Li</pre></div></div></td></tr> 742*67e74705SXin Li 743*67e74705SXin Li 744*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 745*67e74705SXin Liosx.cocoa.UnusedIvars</span><span class="lang"> 746*67e74705SXin Li(ObjC)</span><div class="descr"> 747*67e74705SXin LiWarn about private ivars that are never used.</div></div></td> 748*67e74705SXin Li<td><div class="exampleContainer expandable"> 749*67e74705SXin Li<div class="example"><pre> 750*67e74705SXin Li@interface MyObj : NSObject { 751*67e74705SXin Li@private 752*67e74705SXin Li id x; // warn 753*67e74705SXin Li} 754*67e74705SXin Li@end 755*67e74705SXin Li 756*67e74705SXin Li@implementation MyObj 757*67e74705SXin Li@end 758*67e74705SXin Li</pre></div></div></td></tr> 759*67e74705SXin Li 760*67e74705SXin Li 761*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 762*67e74705SXin Liosx.cocoa.VariadicMethodTypes</span><span class="lang"> 763*67e74705SXin Li(ObjC)</span><div class="descr"> 764*67e74705SXin LiCheck for passing non-Objective-C types to variadic collection initialization 765*67e74705SXin Limethods that expect only Objective-C types.</div></div></td> 766*67e74705SXin Li<td><div class="exampleContainer expandable"> 767*67e74705SXin Li<div class="example"><pre> 768*67e74705SXin Livoid test() { 769*67e74705SXin Li [NSSet setWithObjects:@"Foo", "Bar", nil]; 770*67e74705SXin Li // warn: argument should be an ObjC pointer type, not 'char *' 771*67e74705SXin Li} 772*67e74705SXin Li</pre></div></div></td></tr> 773*67e74705SXin Li 774*67e74705SXin Li 775*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 776*67e74705SXin Liosx.coreFoundation.CFError</span><span class="lang"> 777*67e74705SXin Li(C)</span><div class="descr"> 778*67e74705SXin LiCheck usage of <code>CFErrorRef*</code> parameters.</div></div></td> 779*67e74705SXin Li<td><div class="exampleContainer expandable"> 780*67e74705SXin Li<div class="example"><pre> 781*67e74705SXin Livoid test(CFErrorRef *error) { 782*67e74705SXin Li // warn: function accepting CFErrorRef* should have a 783*67e74705SXin Li // non-void return 784*67e74705SXin Li} 785*67e74705SXin Li</pre></div> 786*67e74705SXin Li<div class="example"><pre> 787*67e74705SXin Liint foo(CFErrorRef *error) { 788*67e74705SXin Li *error = 0; // warn: potential null dereference 789*67e74705SXin Li return 0; 790*67e74705SXin Li} 791*67e74705SXin Li</pre></div></div></td></tr> 792*67e74705SXin Li 793*67e74705SXin Li 794*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 795*67e74705SXin Liosx.coreFoundation.CFNumber</span><span class="lang"> 796*67e74705SXin Li(C)</span><div class="descr"> 797*67e74705SXin LiCheck for improper uses of <code>CFNumberCreate</code>.</div></div></td> 798*67e74705SXin Li<td><div class="exampleContainer expandable"> 799*67e74705SXin Li<div class="example"><pre> 800*67e74705SXin LiCFNumberRef test(unsigned char x) { 801*67e74705SXin Li return CFNumberCreate(0, kCFNumberSInt16Type, &x); 802*67e74705SXin Li // warn: 8 bit integer is used to initialize a 16 bit integer 803*67e74705SXin Li} 804*67e74705SXin Li</pre></div></div></td></tr> 805*67e74705SXin Li 806*67e74705SXin Li 807*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 808*67e74705SXin Liosx.coreFoundation.CFRetainRelease</span><span class="lang"> 809*67e74705SXin Li(C)</span><div class="descr"> 810*67e74705SXin LiCheck for null arguments to <code>CFRetain</code>, <code>CFRelease</code>, 811*67e74705SXin Li<code>CFMakeCollectable</code>.</div></div></td> 812*67e74705SXin Li<td><div class="exampleContainer expandable"> 813*67e74705SXin Li<div class="example"><pre> 814*67e74705SXin Livoid test(CFTypeRef p) { 815*67e74705SXin Li if (!p) 816*67e74705SXin Li CFRetain(p); // warn 817*67e74705SXin Li} 818*67e74705SXin Li</pre></div> 819*67e74705SXin Li<div class="example"><pre> 820*67e74705SXin Livoid test(int x, CFTypeRef p) { 821*67e74705SXin Li if (p) 822*67e74705SXin Li return; 823*67e74705SXin Li 824*67e74705SXin Li CFRelease(p); // warn 825*67e74705SXin Li} 826*67e74705SXin Li</pre></div></div></td></tr> 827*67e74705SXin Li 828*67e74705SXin Li 829*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 830*67e74705SXin Liosx.coreFoundation.containers.OutOfBounds</span><span class="lang"> 831*67e74705SXin Li(C)</span><div class="descr"> 832*67e74705SXin LiChecks for index out-of-bounds when using <code>CFArray</code> API.</div></div></td> 833*67e74705SXin Li<td><div class="exampleContainer expandable"> 834*67e74705SXin Li<div class="example"><pre> 835*67e74705SXin Livoid test() { 836*67e74705SXin Li CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks); 837*67e74705SXin Li CFArrayGetValueAtIndex(A, 0); // warn 838*67e74705SXin Li} 839*67e74705SXin Li</pre></div></div></td></tr> 840*67e74705SXin Li 841*67e74705SXin Li 842*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 843*67e74705SXin Liosx.coreFoundation.containers.PointerSizedValues</span><span class="lang"> 844*67e74705SXin Li(C)</span><div class="descr"> 845*67e74705SXin LiWarns if <code>CFArray</code>, <code>CFDictionary</code>, <code>CFSet</code> are 846*67e74705SXin Licreated with non-pointer-size values.</div></div></td> 847*67e74705SXin Li<td><div class="exampleContainer expandable"> 848*67e74705SXin Li<div class="example"><pre> 849*67e74705SXin Livoid test() { 850*67e74705SXin Li int x[] = { 1 }; 851*67e74705SXin Li CFArrayRef A = CFArrayCreate(0, (const void **)x, 1, 852*67e74705SXin Li &kCFTypeArrayCallBacks); // warn 853*67e74705SXin Li} 854*67e74705SXin Li</pre></div></div></td></tr> 855*67e74705SXin Li 856*67e74705SXin Li</tbody></table> 857*67e74705SXin Li 858*67e74705SXin Li<!------------------------------- security ------------------------------------> 859*67e74705SXin Li<h3 id="security_checkers">Security Checkers</h3> 860*67e74705SXin Li<table class="checkers"> 861*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup> 862*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> 863*67e74705SXin Li 864*67e74705SXin Li<tbody> 865*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 866*67e74705SXin Lisecurity.FloatLoopCounter</span><span class="lang"> 867*67e74705SXin Li(C)</span><div class="descr"> 868*67e74705SXin LiWarn on using a floating point value as a loop counter (CERT: FLP30-C, 869*67e74705SXin LiFLP30-CPP).</div></div></td> 870*67e74705SXin Li<td><div class="exampleContainer expandable"> 871*67e74705SXin Li<div class="example"><pre> 872*67e74705SXin Livoid test() { 873*67e74705SXin Li for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn 874*67e74705SXin Li} 875*67e74705SXin Li</pre></div></div></td></tr> 876*67e74705SXin Li 877*67e74705SXin Li 878*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 879*67e74705SXin Lisecurity.insecureAPI.UncheckedReturn</span><span class="lang"> 880*67e74705SXin Li(C)</span><div class="descr"> 881*67e74705SXin LiWarn on uses of functions whose return values must be always checked:<div class=functions> 882*67e74705SXin Lisetuid<br> 883*67e74705SXin Lisetgid<br> 884*67e74705SXin Liseteuid<br> 885*67e74705SXin Lisetegid<br> 886*67e74705SXin Lisetreuid<br> 887*67e74705SXin Lisetregid</div></div></div></td> 888*67e74705SXin Li<td><div class="exampleContainer expandable"> 889*67e74705SXin Li<div class="example"><pre> 890*67e74705SXin Livoid test() { 891*67e74705SXin Li setuid(1); // warn 892*67e74705SXin Li} 893*67e74705SXin Li</pre></div></div></td></tr> 894*67e74705SXin Li 895*67e74705SXin Li 896*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 897*67e74705SXin Lisecurity.insecureAPI.getpw</span><span class="lang"> 898*67e74705SXin Li(C)</span><div class="descr"> 899*67e74705SXin LiWarn on uses of the <code>getpw</code> function.</div></div></td> 900*67e74705SXin Li<td><div class="exampleContainer expandable"> 901*67e74705SXin Li<div class="example"><pre> 902*67e74705SXin Livoid test() { 903*67e74705SXin Li char buff[1024]; 904*67e74705SXin Li getpw(2, buff); // warn 905*67e74705SXin Li} 906*67e74705SXin Li</pre></div></div></td></tr> 907*67e74705SXin Li 908*67e74705SXin Li 909*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 910*67e74705SXin Lisecurity.insecureAPI.gets</span><span class="lang"> 911*67e74705SXin Li(C)</span><div class="descr"> 912*67e74705SXin LiWarn on uses of the <code>gets</code> function.</div></div></td> 913*67e74705SXin Li<td><div class="exampleContainer expandable"> 914*67e74705SXin Li<div class="example"><pre> 915*67e74705SXin Livoid test() { 916*67e74705SXin Li char buff[1024]; 917*67e74705SXin Li gets(buff); // warn 918*67e74705SXin Li} 919*67e74705SXin Li</pre></div></div></td></tr> 920*67e74705SXin Li 921*67e74705SXin Li 922*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 923*67e74705SXin Lisecurity.insecureAPI.mkstemp</span><span class="lang"> 924*67e74705SXin Li(C)</span><div class="descr"> 925*67e74705SXin LiWarn when <code>mktemp</code>, <code>mkstemp</code>, <code>mkstemps</code> or 926*67e74705SXin Li<code>mkdtemp</code> is passed fewer than 6 927*67e74705SXin LiX's in the format string.</div></div></td> 928*67e74705SXin Li<td><div class="exampleContainer expandable"> 929*67e74705SXin Li<div class="example"><pre> 930*67e74705SXin Livoid test() { 931*67e74705SXin Li mkstemp("XX"); // warn 932*67e74705SXin Li} 933*67e74705SXin Li</pre></div></div></td></tr> 934*67e74705SXin Li 935*67e74705SXin Li 936*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 937*67e74705SXin Lisecurity.insecureAPI.mktemp</span><span class="lang"> 938*67e74705SXin Li(C)</span><div class="descr"> 939*67e74705SXin LiWarn on uses of the <code>mktemp</code> function.</div></div></td> 940*67e74705SXin Li<td><div class="exampleContainer expandable"> 941*67e74705SXin Li<div class="example"><pre> 942*67e74705SXin Livoid test() { 943*67e74705SXin Li char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp 944*67e74705SXin Li} 945*67e74705SXin Li</pre></div></div></td></tr> 946*67e74705SXin Li 947*67e74705SXin Li 948*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 949*67e74705SXin Lisecurity.insecureAPI.rand</span><span class="lang"> 950*67e74705SXin Li(C)</span><div class="descr"> 951*67e74705SXin LiWarn on uses of inferior random number generating functions (only if <code>arc4random</code> 952*67e74705SXin Lifunction is available):<div class=functions> 953*67e74705SXin Lidrand48<br> 954*67e74705SXin Lierand48<br> 955*67e74705SXin Lijrand48<br> 956*67e74705SXin Lilcong48<br> 957*67e74705SXin Lilrand48<br> 958*67e74705SXin Limrand48<br> 959*67e74705SXin Linrand48<br> 960*67e74705SXin Lirandom<br> 961*67e74705SXin Lirand_r</div></div></div></td> 962*67e74705SXin Li<td><div class="exampleContainer expandable"> 963*67e74705SXin Li<div class="example"><pre> 964*67e74705SXin Livoid test() { 965*67e74705SXin Li random(); // warn 966*67e74705SXin Li} 967*67e74705SXin Li</pre></div></div></td></tr> 968*67e74705SXin Li 969*67e74705SXin Li 970*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 971*67e74705SXin Lisecurity.insecureAPI.strcpy</span><span class="lang"> 972*67e74705SXin Li(C)</span><div class="descr"> 973*67e74705SXin LiWarn on uses of the <code>strcpy</code> and <code>strcat</code> functions.</div></div></td> 974*67e74705SXin Li<td><div class="exampleContainer expandable"> 975*67e74705SXin Li<div class="example"><pre> 976*67e74705SXin Livoid test() { 977*67e74705SXin Li char x[4]; 978*67e74705SXin Li char *y = "abcd"; 979*67e74705SXin Li 980*67e74705SXin Li strcpy(x, y); // warn 981*67e74705SXin Li} 982*67e74705SXin Li</pre></div></div></td></tr> 983*67e74705SXin Li 984*67e74705SXin Li 985*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 986*67e74705SXin Lisecurity.insecureAPI.vfork</span><span class="lang"> 987*67e74705SXin Li(C)</span><div class="descr"> 988*67e74705SXin LiWarn on uses of the <code>vfork</code> function.</div></div></td> 989*67e74705SXin Li<td><div class="exampleContainer expandable"> 990*67e74705SXin Li<div class="example"><pre> 991*67e74705SXin Livoid test() { 992*67e74705SXin Li vfork(); // warn 993*67e74705SXin Li} 994*67e74705SXin Li</pre></div></div></td></tr> 995*67e74705SXin Li 996*67e74705SXin Li</tbody></table> 997*67e74705SXin Li 998*67e74705SXin Li<!--------------------------------- unix --------------------------------------> 999*67e74705SXin Li<h3 id="unix_checkers">Unix Checkers</h3> 1000*67e74705SXin Li<table class="checkers"> 1001*67e74705SXin Li<colgroup><col class="namedescr"><col class="example"></colgroup> 1002*67e74705SXin Li<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> 1003*67e74705SXin Li 1004*67e74705SXin Li<tbody> 1005*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 1006*67e74705SXin Liunix.API</span><span class="lang"> 1007*67e74705SXin Li(C)</span><div class="descr"> 1008*67e74705SXin LiCheck calls to various UNIX/POSIX functions:<div class=functions> 1009*67e74705SXin Liopen<br> 1010*67e74705SXin Lipthread_once<br> 1011*67e74705SXin Licalloc<br> 1012*67e74705SXin Limalloc<br> 1013*67e74705SXin Lirealloc<br> 1014*67e74705SXin Lialloca<br> 1015*67e74705SXin Li<td><div class="exampleContainer expandable"> 1016*67e74705SXin Li<div class="example"><pre> 1017*67e74705SXin Li// Currently the check is performed for apple targets only. 1018*67e74705SXin Livoid test(const char *path) { 1019*67e74705SXin Li int fd = open(path, O_CREAT); 1020*67e74705SXin Li // warn: call to 'open' requires a third argument when the 1021*67e74705SXin Li // 'O_CREAT' flag is set 1022*67e74705SXin Li} 1023*67e74705SXin Li</pre></div> 1024*67e74705SXin Li<div class="example"><pre> 1025*67e74705SXin Livoid f(); 1026*67e74705SXin Li 1027*67e74705SXin Livoid test() { 1028*67e74705SXin Li pthread_once_t pred = {0x30B1BCBA, {0}}; 1029*67e74705SXin Li pthread_once(&pred, f); 1030*67e74705SXin Li // warn: call to 'pthread_once' uses the local variable 1031*67e74705SXin Li} 1032*67e74705SXin Li</pre></div> 1033*67e74705SXin Li<div class="example"><pre> 1034*67e74705SXin Livoid test() { 1035*67e74705SXin Li void *p = malloc(0); // warn: allocation size of 0 bytes 1036*67e74705SXin Li} 1037*67e74705SXin Li</pre></div> 1038*67e74705SXin Li<div class="example"><pre> 1039*67e74705SXin Livoid test() { 1040*67e74705SXin Li void *p = calloc(0, 42); // warn: allocation size of 0 bytes 1041*67e74705SXin Li} 1042*67e74705SXin Li</pre></div> 1043*67e74705SXin Li<div class="example"><pre> 1044*67e74705SXin Livoid test() { 1045*67e74705SXin Li void *p = malloc(1); 1046*67e74705SXin Li p = realloc(p, 0); // warn: allocation size of 0 bytes 1047*67e74705SXin Li} 1048*67e74705SXin Li</pre></div> 1049*67e74705SXin Li<div class="example"><pre> 1050*67e74705SXin Livoid test() { 1051*67e74705SXin Li void *p = alloca(0); // warn: allocation size of 0 bytes 1052*67e74705SXin Li} 1053*67e74705SXin Li</pre></div> 1054*67e74705SXin Li<div class="example"><pre> 1055*67e74705SXin Livoid test() { 1056*67e74705SXin Li void *p = valloc(0); // warn: allocation size of 0 bytes 1057*67e74705SXin Li} 1058*67e74705SXin Li</pre></div></div></td></tr> 1059*67e74705SXin Li 1060*67e74705SXin Li 1061*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 1062*67e74705SXin Liunix.Malloc</span><span class="lang"> 1063*67e74705SXin Li(C)</span><div class="descr"> 1064*67e74705SXin LiCheck for memory leaks, double free, and use-after-free and offset problems 1065*67e74705SXin Liinvolving <code>malloc</code>.</div></div></td> 1066*67e74705SXin Li<td><div class="exampleContainer expandable"> 1067*67e74705SXin Li<div class="example"><pre> 1068*67e74705SXin Livoid test() { 1069*67e74705SXin Li int *p = malloc(1); 1070*67e74705SXin Li free(p); 1071*67e74705SXin Li free(p); // warn: attempt to free released memory 1072*67e74705SXin Li} 1073*67e74705SXin Li</pre></div> 1074*67e74705SXin Li<div class="example"><pre> 1075*67e74705SXin Livoid test() { 1076*67e74705SXin Li int *p = malloc(sizeof(int)); 1077*67e74705SXin Li free(p); 1078*67e74705SXin Li *p = 1; // warn: use after free 1079*67e74705SXin Li} 1080*67e74705SXin Li</pre></div> 1081*67e74705SXin Li<div class="example"><pre> 1082*67e74705SXin Livoid test() { 1083*67e74705SXin Li int *p = malloc(1); 1084*67e74705SXin Li if (p) 1085*67e74705SXin Li return; // warn: memory is never released 1086*67e74705SXin Li} 1087*67e74705SXin Li</pre></div> 1088*67e74705SXin Li<div class="example"><pre> 1089*67e74705SXin Livoid test() { 1090*67e74705SXin Li int a[] = { 1 }; 1091*67e74705SXin Li free(a); // warn: argument is not allocated by malloc 1092*67e74705SXin Li} 1093*67e74705SXin Li</pre></div> 1094*67e74705SXin Li<div class="example"><pre> 1095*67e74705SXin Livoid test() { 1096*67e74705SXin Li int *p = malloc(sizeof(char)); 1097*67e74705SXin Li p = p - 1; 1098*67e74705SXin Li free(p); // warn: argument to free() is offset by -4 bytes 1099*67e74705SXin Li} 1100*67e74705SXin Li</pre></div></div></td></tr> 1101*67e74705SXin Li 1102*67e74705SXin Li 1103*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 1104*67e74705SXin Liunix.MallocSizeof</span><span class="lang"> 1105*67e74705SXin Li(C)</span><div class="descr"> 1106*67e74705SXin LiCheck for dubious <code>malloc</code>, <code>calloc</code> or 1107*67e74705SXin Li<code>realloc</code> arguments involving <code>sizeof</code>.</div></div></td> 1108*67e74705SXin Li<td><div class="exampleContainer expandable"> 1109*67e74705SXin Li<div class="example"><pre> 1110*67e74705SXin Livoid test() { 1111*67e74705SXin Li long *p = malloc(sizeof(short)); 1112*67e74705SXin Li // warn: result is converted to 'long *', which is 1113*67e74705SXin Li // incompatible with operand type 'short' 1114*67e74705SXin Li free(p); 1115*67e74705SXin Li} 1116*67e74705SXin Li</pre></div></div></td></tr> 1117*67e74705SXin Li 1118*67e74705SXin Li 1119*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 1120*67e74705SXin Liunix.MismatchedDeallocator</span><span class="lang"> 1121*67e74705SXin Li(C, C++, ObjC)</span><div class="descr"> 1122*67e74705SXin LiCheck for mismatched deallocators (e.g. passing a pointer allocating 1123*67e74705SXin Liwith <code>new</code> to <code>free()</code>).</div></div></td> 1124*67e74705SXin Li<td><div class="exampleContainer expandable"> 1125*67e74705SXin Li<div class="example"><pre> 1126*67e74705SXin Li// C, C++ 1127*67e74705SXin Livoid test() { 1128*67e74705SXin Li int *p = (int *)malloc(sizeof(int)); 1129*67e74705SXin Li delete p; // warn 1130*67e74705SXin Li} 1131*67e74705SXin Li</pre></div> 1132*67e74705SXin Li<div class="example"><pre> 1133*67e74705SXin Li// C, C++ 1134*67e74705SXin Livoid __attribute((ownership_returns(malloc))) *user_malloc(size_t); 1135*67e74705SXin Li 1136*67e74705SXin Livoid test() { 1137*67e74705SXin Li int *p = (int *)user_malloc(sizeof(int)); 1138*67e74705SXin Li delete p; // warn 1139*67e74705SXin Li} 1140*67e74705SXin Li</pre></div> 1141*67e74705SXin Li<div class="example"><pre> 1142*67e74705SXin Li// C, C++ 1143*67e74705SXin Livoid test() { 1144*67e74705SXin Li int *p = new int; 1145*67e74705SXin Li free(p); // warn 1146*67e74705SXin Li} 1147*67e74705SXin Li</pre></div> 1148*67e74705SXin Li<div class="example"><pre> 1149*67e74705SXin Li// C, C++ 1150*67e74705SXin Livoid test() { 1151*67e74705SXin Li int *p = new int[1]; 1152*67e74705SXin Li realloc(p, sizeof(long)); // warn 1153*67e74705SXin Li} 1154*67e74705SXin Li</pre></div> 1155*67e74705SXin Li<div class="example"><pre> 1156*67e74705SXin Li// C, C++ 1157*67e74705SXin Litemplate <typename T> 1158*67e74705SXin Listruct SimpleSmartPointer { 1159*67e74705SXin Li T *ptr; 1160*67e74705SXin Li 1161*67e74705SXin Li explicit SimpleSmartPointer(T *p = 0) : ptr(p) {} 1162*67e74705SXin Li ~SimpleSmartPointer() { 1163*67e74705SXin Li delete ptr; // warn 1164*67e74705SXin Li } 1165*67e74705SXin Li}; 1166*67e74705SXin Li 1167*67e74705SXin Livoid test() { 1168*67e74705SXin Li SimpleSmartPointer<int> a((int *)malloc(4)); 1169*67e74705SXin Li} 1170*67e74705SXin Li</pre></div> 1171*67e74705SXin Li<div class="example"><pre> 1172*67e74705SXin Li// C++ 1173*67e74705SXin Livoid test() { 1174*67e74705SXin Li int *p = (int *)operator new(0); 1175*67e74705SXin Li delete[] p; // warn 1176*67e74705SXin Li} 1177*67e74705SXin Li</pre></div> 1178*67e74705SXin Li<div class="example"><pre> 1179*67e74705SXin Li// Objective-C, C++ 1180*67e74705SXin Livoid test(NSUInteger dataLength) { 1181*67e74705SXin Li int *p = new int; 1182*67e74705SXin Li NSData *d = [NSData dataWithBytesNoCopy:p 1183*67e74705SXin Li length:sizeof(int) freeWhenDone:1]; 1184*67e74705SXin Li // warn +dataWithBytesNoCopy:length:freeWhenDone: cannot take 1185*67e74705SXin Li // ownership of memory allocated by 'new' 1186*67e74705SXin Li} 1187*67e74705SXin Li</pre></div></div></td></tr> 1188*67e74705SXin Li 1189*67e74705SXin Li 1190*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 1191*67e74705SXin Liunix.cstring.BadSizeArg</span><span class="lang"> 1192*67e74705SXin Li(C)</span><div class="descr"> 1193*67e74705SXin LiCheck the size argument passed to <code>strncat</code> for common erroneous 1194*67e74705SXin Lipatterns. Use <code>-Wno-strncat-size</code> compiler option to mute other 1195*67e74705SXin Li<code>strncat</code>-related compiler warnings. 1196*67e74705SXin Li</div></div></td> 1197*67e74705SXin Li<td><div class="exampleContainer expandable"> 1198*67e74705SXin Li<div class="example"><pre> 1199*67e74705SXin Livoid test() { 1200*67e74705SXin Li char dest[3]; 1201*67e74705SXin Li strncat(dest, "***", sizeof(dest)); 1202*67e74705SXin Li // warn: potential buffer overflow 1203*67e74705SXin Li} 1204*67e74705SXin Li</pre></div></div></td></tr> 1205*67e74705SXin Li 1206*67e74705SXin Li 1207*67e74705SXin Li<tr><td><div class="namedescr expandable"><span class="name"> 1208*67e74705SXin Liunix.cstring.NullArg</span><span class="lang"> 1209*67e74705SXin Li(C)</span><div class="descr"> 1210*67e74705SXin LiCheck for null pointers being passed as arguments to C string functions:<div class=functions> 1211*67e74705SXin Listrlen<br> 1212*67e74705SXin Listrnlen<br> 1213*67e74705SXin Listrcpy<br> 1214*67e74705SXin Listrncpy<br> 1215*67e74705SXin Listrcat<br> 1216*67e74705SXin Listrncat<br> 1217*67e74705SXin Listrcmp<br> 1218*67e74705SXin Listrncmp<br> 1219*67e74705SXin Listrcasecmp<br> 1220*67e74705SXin Listrncasecmp</div></div></div></td> 1221*67e74705SXin Li<td><div class="example"><pre> 1222*67e74705SXin Liint test() { 1223*67e74705SXin Li return strlen(0); // warn 1224*67e74705SXin Li} 1225*67e74705SXin Li</pre></div></td></tr> 1226*67e74705SXin Li 1227*67e74705SXin Li</tbody></table> 1228*67e74705SXin Li 1229*67e74705SXin Li</div> <!-- page --> 1230*67e74705SXin Li</div> <!-- content --> 1231*67e74705SXin Li</body> 1232*67e74705SXin Li</html> 1233