284 lines
4.4 KiB
Plaintext
284 lines
4.4 KiB
Plaintext
// SPDX-License-Identifier: GPL-2.0-only
|
|
///
|
|
/// A variable is dereferenced under a NULL test.
|
|
/// Even though it is known to be NULL.
|
|
///
|
|
// Confidence: Moderate
|
|
// Copyright: (C) 2010 Nicolas Palix, DIKU.
|
|
// Copyright: (C) 2010 Julia Lawall, DIKU.
|
|
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.
|
|
// URL: http://coccinelle.lip6.fr/
|
|
// Comments: -I ... -all_includes can give more complete results
|
|
// Options:
|
|
|
|
virtual context
|
|
virtual org
|
|
virtual report
|
|
|
|
// The following two rules are separate, because both can match a single
|
|
// expression in different ways
|
|
@pr1 expression@
|
|
expression E;
|
|
identifier f;
|
|
position p1;
|
|
@@
|
|
|
|
(E != NULL && ...) ? <+...E->f@p1...+> : ...
|
|
|
|
@pr2 expression@
|
|
expression E;
|
|
identifier f;
|
|
position p2;
|
|
@@
|
|
|
|
(
|
|
(E != NULL) && ... && <+...E->f@p2...+>
|
|
|
|
|
(E == NULL) || ... || <+...E->f@p2...+>
|
|
|
|
|
sizeof(<+...E->f@p2...+>)
|
|
)
|
|
|
|
@ifm@
|
|
expression *E;
|
|
statement S1,S2;
|
|
position p1;
|
|
@@
|
|
|
|
if@p1 ((E == NULL && ...) || ...) S1 else S2
|
|
|
|
// For org and report modes
|
|
|
|
@r depends on !context && (org || report) exists@
|
|
expression subE <= ifm.E;
|
|
expression *ifm.E;
|
|
expression E1,E2;
|
|
identifier f;
|
|
statement S1,S2,S3,S4;
|
|
iterator iter;
|
|
position p!={pr1.p1,pr2.p2};
|
|
position ifm.p1;
|
|
@@
|
|
|
|
if@p1 ((E == NULL && ...) || ...)
|
|
{
|
|
... when != if (...) S1 else S2
|
|
(
|
|
iter(subE,...) S4 // no use
|
|
|
|
|
list_remove_head(E2,subE,...)
|
|
|
|
|
subE = E1
|
|
|
|
|
for(subE = E1;...;...) S4
|
|
|
|
|
subE++
|
|
|
|
|
++subE
|
|
|
|
|
--subE
|
|
|
|
|
subE--
|
|
|
|
|
&subE
|
|
|
|
|
E->f@p // bad use
|
|
)
|
|
... when any
|
|
return ...;
|
|
}
|
|
else S3
|
|
|
|
@script:python depends on !context && !org && report@
|
|
p << r.p;
|
|
p1 << ifm.p1;
|
|
x << ifm.E;
|
|
@@
|
|
|
|
msg="ERROR: %s is NULL but dereferenced." % (x)
|
|
coccilib.report.print_report(p[0], msg)
|
|
cocci.include_match(False)
|
|
|
|
@script:python depends on !context && org && !report@
|
|
p << r.p;
|
|
p1 << ifm.p1;
|
|
x << ifm.E;
|
|
@@
|
|
|
|
msg="ERROR: %s is NULL but dereferenced." % (x)
|
|
msg_safe=msg.replace("[","@(").replace("]",")")
|
|
cocci.print_main(msg_safe,p)
|
|
cocci.include_match(False)
|
|
|
|
@s depends on !context && (org || report) exists@
|
|
expression subE <= ifm.E;
|
|
expression *ifm.E;
|
|
expression E1,E2;
|
|
identifier f;
|
|
statement S1,S2,S3,S4;
|
|
iterator iter;
|
|
position p!={pr1.p1,pr2.p2};
|
|
position ifm.p1;
|
|
@@
|
|
|
|
if@p1 ((E == NULL && ...) || ...)
|
|
{
|
|
... when != if (...) S1 else S2
|
|
(
|
|
iter(subE,...) S4 // no use
|
|
|
|
|
list_remove_head(E2,subE,...)
|
|
|
|
|
subE = E1
|
|
|
|
|
for(subE = E1;...;...) S4
|
|
|
|
|
subE++
|
|
|
|
|
++subE
|
|
|
|
|
--subE
|
|
|
|
|
subE--
|
|
|
|
|
&subE
|
|
|
|
|
E->f@p // bad use
|
|
)
|
|
... when any
|
|
}
|
|
else S3
|
|
|
|
@script:python depends on !context && !org && report@
|
|
p << s.p;
|
|
p1 << ifm.p1;
|
|
x << ifm.E;
|
|
@@
|
|
|
|
msg="ERROR: %s is NULL but dereferenced." % (x)
|
|
coccilib.report.print_report(p[0], msg)
|
|
|
|
@script:python depends on !context && org && !report@
|
|
p << s.p;
|
|
p1 << ifm.p1;
|
|
x << ifm.E;
|
|
@@
|
|
|
|
msg="ERROR: %s is NULL but dereferenced." % (x)
|
|
msg_safe=msg.replace("[","@(").replace("]",")")
|
|
cocci.print_main(msg_safe,p)
|
|
|
|
// For context mode
|
|
|
|
@depends on context && !org && !report exists@
|
|
expression subE <= ifm.E;
|
|
expression *ifm.E;
|
|
expression E1,E2;
|
|
identifier f;
|
|
statement S1,S2,S3,S4;
|
|
iterator iter;
|
|
position p!={pr1.p1,pr2.p2};
|
|
position ifm.p1;
|
|
@@
|
|
|
|
if@p1 ((E == NULL && ...) || ...)
|
|
{
|
|
... when != if (...) S1 else S2
|
|
(
|
|
iter(subE,...) S4 // no use
|
|
|
|
|
list_remove_head(E2,subE,...)
|
|
|
|
|
subE = E1
|
|
|
|
|
for(subE = E1;...;...) S4
|
|
|
|
|
subE++
|
|
|
|
|
++subE
|
|
|
|
|
--subE
|
|
|
|
|
subE--
|
|
|
|
|
&subE
|
|
|
|
|
* E->f@p // bad use
|
|
)
|
|
... when any
|
|
return ...;
|
|
}
|
|
else S3
|
|
|
|
// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
|
|
// It is need because the previous rule as already made a "change".
|
|
|
|
@pr11 depends on context && !org && !report expression@
|
|
expression E;
|
|
identifier f;
|
|
position p1;
|
|
@@
|
|
|
|
(E != NULL && ...) ? <+...E->f@p1...+> : ...
|
|
|
|
@pr12 depends on context && !org && !report expression@
|
|
expression E;
|
|
identifier f;
|
|
position p2;
|
|
@@
|
|
|
|
(
|
|
(E != NULL) && ... && <+...E->f@p2...+>
|
|
|
|
|
(E == NULL) || ... || <+...E->f@p2...+>
|
|
|
|
|
sizeof(<+...E->f@p2...+>)
|
|
)
|
|
|
|
@ifm1 depends on context && !org && !report@
|
|
expression *E;
|
|
statement S1,S2;
|
|
position p1;
|
|
@@
|
|
|
|
if@p1 ((E == NULL && ...) || ...) S1 else S2
|
|
|
|
@depends on context && !org && !report exists@
|
|
expression subE <= ifm1.E;
|
|
expression *ifm1.E;
|
|
expression E1,E2;
|
|
identifier f;
|
|
statement S1,S2,S3,S4;
|
|
iterator iter;
|
|
position p!={pr11.p1,pr12.p2};
|
|
position ifm1.p1;
|
|
@@
|
|
|
|
if@p1 ((E == NULL && ...) || ...)
|
|
{
|
|
... when != if (...) S1 else S2
|
|
(
|
|
iter(subE,...) S4 // no use
|
|
|
|
|
list_remove_head(E2,subE,...)
|
|
|
|
|
subE = E1
|
|
|
|
|
for(subE = E1;...;...) S4
|
|
|
|
|
subE++
|
|
|
|
|
++subE
|
|
|
|
|
--subE
|
|
|
|
|
subE--
|
|
|
|
|
&subE
|
|
|
|
|
* E->f@p // bad use
|
|
)
|
|
... when any
|
|
}
|
|
else S3
|