-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathtest.c
More file actions
153 lines (116 loc) · 2.83 KB
/
test.c
File metadata and controls
153 lines (116 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <stdlib.h>
int f1();
void (*g1)(void);
int (*g2)(int);
void *g3 = NULL;
struct S {
int (*fp)(void);
int x;
};
typedef int (*handler_t)(void);
handler_t get_handler(void);
void f2(void) {
if (f1 == 0) // NON-COMPLIANT
return;
if (f1 > 0) // NON-COMPLIANT
return;
if (f1() == 0) // COMPLIANT
return;
if (f1() > 0) // COMPLIANT
return;
if (g1 == 0) // NON-COMPLIANT
return;
if (g2 == NULL) // NON-COMPLIANT
return;
if (g1 != 0x0) // NON-COMPLIANT
return;
if (f1) // NON-COMPLIANT - implicit comparison
return;
if (g1) // NON-COMPLIANT - implicit comparison
return;
}
void f3(void *p1) {
if (g1 == p1) // COMPLIANT - comparing to variable
return;
if (g2 == g3) // COMPLIANT - comparing to variable
return;
}
void f4(void) {
int (*l1)(void) = 0;
if (f1 == f1) // COMPLIANT - comparing to constant value of same type
return;
if (f1 == l1) // COMPLIANT - comparing to constant value of same type
return;
if (f1 == (int (*)(void))0) // COMPLIANT - explicit cast
return;
if (f1 == (int (*)(void))0) // COMPLIANT - explicit cast
return;
if (f1 == (int (*)(int))0) // NON-COMPLIANT - explicit cast to wrong type
return;
if (f1 == (int)0) // NON-COMPLIANT - cast to non-function pointer type
return;
if (f1 ==
(int)(int (*)(void))
NULL) // NON-COMPLIANT - compliant cast subsumed by non-compliant cast
return;
}
typedef void (*func_t)(void);
void f5(void) {
func_t l1 = g1;
l1 == 0; // NON-COMPLIANT
l1 == NULL; // NON-COMPLIANT
l1 == (func_t)0; // COMPLIANT - cast to function pointer type
}
void f6(void) {
g1 + 0; // COMPLIANT - not a comparison
g1 == g2; // COMPLIANT - not comparing to constant
g1 ? 1 : 0; // NON-COMPLIANT - implicit comparison
}
void f7(void) {
struct S s;
if (s.fp == NULL) // NON-COMPLIANT
f1();
if (s.fp() == NULL) // COMPLIANT
return;
if (get_handler == 0) // NON-COMPLIANT - missing parentheses
return;
if (get_handler() == 0) // NON-COMPLIANT
return;
if (get_handler() == (handler_t)0) // COMPLIANT
return;
if (get_handler()() == 0) // COMPLIANT
return;
}
void f8(void) {
// Test instances of where the function pointer check is used to guard calls
// to that function.
// Technically, this function may perhaps be set to NULL by the linker. But
// it is not a variable that should need to be null-checked at runtime.
if (f1 != 0) // NON-COMPLIANT
{
f1();
}
// Check guards a call, so it is compliant.
if (g1 != 0) // COMPLIANT
{
g1();
}
// Incorrect check, not compliant.
if (g1 != 0) // NON-COMPLIANT
{
f1();
}
// Incorrect check, not compliant.
if (g1 == 0) // NON-COMPLIANT
{
g1();
}
if (g1) // COMPLIANT
{
g1();
}
if (!g1) // NON-COMPLIANT
{
g1();
}
}