1/// 2/// A variable is dereference under a NULL test. 3/// Even though it is know to be NULL. 4/// 5// Confidence: Moderate 6// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 7// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 8// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 9// URL: http://coccinelle.lip6.fr/ 10// Comments: -I ... -all_includes can give more complete results 11// Options: 12 13virtual context 14virtual patch 15virtual org 16virtual report 17 18@initialize:python depends on !context && patch && !org && !report@ 19 20import sys 21print >> sys.stderr, "This semantic patch does not support the 'patch' mode." 22 23@depends on patch@ 24@@ 25 26this_rule_should_never_matches(); 27 28@ifm depends on !patch@ 29expression *E; 30statement S1,S2; 31position p1; 32@@ 33 34if@p1 ((E == NULL && ...) || ...) S1 else S2 35 36// The following two rules are separate, because both can match a single 37// expression in different ways 38@pr1 depends on !patch expression@ 39expression *ifm.E; 40identifier f; 41position p1; 42@@ 43 44 (E != NULL && ...) ? <+...E->f@p1...+> : ... 45 46@pr2 depends on !patch expression@ 47expression *ifm.E; 48identifier f; 49position p2; 50@@ 51 52( 53 (E != NULL) && ... && <+...E->f@p2...+> 54| 55 (E == NULL) || ... || <+...E->f@p2...+> 56| 57 sizeof(<+...E->f@p2...+>) 58) 59 60// For org and report modes 61 62@r depends on !context && !patch && (org || report) exists@ 63expression subE <= ifm.E; 64expression *ifm.E; 65expression E1,E2; 66identifier f; 67statement S1,S2,S3,S4; 68iterator iter; 69position p!={pr1.p1,pr2.p2}; 70position ifm.p1; 71@@ 72 73if@p1 ((E == NULL && ...) || ...) 74{ 75 ... when != if (...) S1 else S2 76( 77 iter(subE,...) S4 // no use 78| 79 list_remove_head(E2,subE,...) 80| 81 subE = E1 82| 83 for(subE = E1;...;...) S4 84| 85 subE++ 86| 87 ++subE 88| 89 --subE 90| 91 subE-- 92| 93 &subE 94| 95 E->f@p // bad use 96) 97 ... when any 98 return ...; 99} 100else S3 101 102@script:python depends on !context && !patch && !org && report@ 103p << r.p; 104p1 << ifm.p1; 105x << ifm.E; 106@@ 107 108msg="ERROR: %s is NULL but dereferenced." % (x) 109coccilib.report.print_report(p[0], msg) 110cocci.include_match(False) 111 112@script:python depends on !context && !patch && org && !report@ 113p << r.p; 114p1 << ifm.p1; 115x << ifm.E; 116@@ 117 118msg="ERROR: %s is NULL but dereferenced." % (x) 119msg_safe=msg.replace("[","@(").replace("]",")") 120cocci.print_main(msg_safe,p) 121cocci.include_match(False) 122 123@s depends on !context && !patch && (org || report) exists@ 124expression subE <= ifm.E; 125expression *ifm.E; 126expression E1,E2; 127identifier f; 128statement S1,S2,S3,S4; 129iterator iter; 130position p!={pr1.p1,pr2.p2}; 131position ifm.p1; 132@@ 133 134if@p1 ((E == NULL && ...) || ...) 135{ 136 ... when != if (...) S1 else S2 137( 138 iter(subE,...) S4 // no use 139| 140 list_remove_head(E2,subE,...) 141| 142 subE = E1 143| 144 for(subE = E1;...;...) S4 145| 146 subE++ 147| 148 ++subE 149| 150 --subE 151| 152 subE-- 153| 154 &subE 155| 156 E->f@p // bad use 157) 158 ... when any 159} 160else S3 161 162@script:python depends on !context && !patch && !org && report@ 163p << s.p; 164p1 << ifm.p1; 165x << ifm.E; 166@@ 167 168msg="ERROR: %s is NULL but dereferenced." % (x) 169coccilib.report.print_report(p[0], msg) 170 171@script:python depends on !context && !patch && org && !report@ 172p << s.p; 173p1 << ifm.p1; 174x << ifm.E; 175@@ 176 177msg="ERROR: %s is NULL but dereferenced." % (x) 178msg_safe=msg.replace("[","@(").replace("]",")") 179cocci.print_main(msg_safe,p) 180 181// For context mode 182 183@depends on context && !patch && !org && !report exists@ 184expression subE <= ifm.E; 185expression *ifm.E; 186expression E1,E2; 187identifier f; 188statement S1,S2,S3,S4; 189iterator iter; 190position p!={pr1.p1,pr2.p2}; 191position ifm.p1; 192@@ 193 194if@p1 ((E == NULL && ...) || ...) 195{ 196 ... when != if (...) S1 else S2 197( 198 iter(subE,...) S4 // no use 199| 200 list_remove_head(E2,subE,...) 201| 202 subE = E1 203| 204 for(subE = E1;...;...) S4 205| 206 subE++ 207| 208 ++subE 209| 210 --subE 211| 212 subE-- 213| 214 &subE 215| 216* E->f@p // bad use 217) 218 ... when any 219 return ...; 220} 221else S3 222 223// The following three rules are duplicates of ifm, pr1 and pr2 respectively. 224// It is need because the previous rule as already made a "change". 225 226@ifm1 depends on !patch@ 227expression *E; 228statement S1,S2; 229position p1; 230@@ 231 232if@p1 ((E == NULL && ...) || ...) S1 else S2 233 234@pr11 depends on !patch expression@ 235expression *ifm1.E; 236identifier f; 237position p1; 238@@ 239 240 (E != NULL && ...) ? <+...E->f@p1...+> : ... 241 242@pr12 depends on !patch expression@ 243expression *ifm1.E; 244identifier f; 245position p2; 246@@ 247 248( 249 (E != NULL) && ... && <+...E->f@p2...+> 250| 251 (E == NULL) || ... || <+...E->f@p2...+> 252| 253 sizeof(<+...E->f@p2...+>) 254) 255 256@depends on context && !patch && !org && !report exists@ 257expression subE <= ifm1.E; 258expression *ifm1.E; 259expression E1,E2; 260identifier f; 261statement S1,S2,S3,S4; 262iterator iter; 263position p!={pr11.p1,pr12.p2}; 264position ifm1.p1; 265@@ 266 267if@p1 ((E == NULL && ...) || ...) 268{ 269 ... when != if (...) S1 else S2 270( 271 iter(subE,...) S4 // no use 272| 273 list_remove_head(E2,subE,...) 274| 275 subE = E1 276| 277 for(subE = E1;...;...) S4 278| 279 subE++ 280| 281 ++subE 282| 283 --subE 284| 285 subE-- 286| 287 &subE 288| 289* E->f@p // bad use 290) 291 ... when any 292} 293else S3 294