1 // RUN: %clang_analyze_cc1 \
2 // RUN: -analyzer-checker=security.cert.env.InvalidPtr\
3 // RUN: -analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=true \
4 // RUN: -analyzer-output=text -verify -Wno-unused %s
6 #include "../Inputs/system-header-simulator.h"
7 char *getenv(const char *name
);
8 char *setlocale(int category
, const char *locale
);
9 char *strerror(int errnum
);
14 lconv
*localeconv(void);
18 char *asctime(const tm
*timeptr
);
20 int strcmp(const char*, const char*);
21 extern void foo(char *e
);
22 extern char* bar(void);
25 void getenv_test1(void) {
32 *p
; // no-warning, getenv result was assigned to the same pointer
35 void getenv_test2(void) {
39 // expected-note@-1{{previous function call was here}}
43 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
46 // expected-warning@-1{{dereferencing an invalid pointer}}
47 // expected-note@-2{{dereferencing an invalid pointer}}
50 void getenv_test3(void) {
57 // expected-note@-1{{previous function call was here}}
59 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
64 // expected-warning@-1{{dereferencing an invalid pointer}}
65 // expected-note@-2{{dereferencing an invalid pointer}}
68 void getenv_test4(void) {
72 // expected-note@-1{{previous function call was here}}
74 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
78 // expected-warning@-1{{dereferencing an invalid pointer}}
79 // expected-note@-2{{dereferencing an invalid pointer}}
82 void getenv_test5(void) {
87 // expected-note@-1{{previous function call was here}}
89 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
92 // expected-warning@-1{{dereferencing an invalid pointer}}
93 // expected-note@-2{{dereferencing an invalid pointer}}
96 void getenv_test6(void) {
102 // expected-note@-1{{previous function call was here}}
106 // expected-note@-1{{previous function call was here}}
107 // expected-note@-2{{'getenv' call may invalidate the result of the previous 'getenv'}}
110 // expected-warning@-1{{dereferencing an invalid pointer}}
111 // expected-note@-2{{dereferencing an invalid pointer}}
116 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
120 // expected-warning@-1{{dereferencing an invalid pointer}}
121 // expected-note@-2{{dereferencing an invalid pointer}}
124 void getenv_test7(void) {
127 // expected-note@-1{{previous function call was here}}
131 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
134 // expected-warning@-1{{use of invalidated pointer 'p' in a function call}}
135 // expected-note@-2{{use of invalidated pointer 'p' in a function call}}
138 void getenv_test8(void) {
139 static const char *array
[] = {
149 // expected-note@-1{{Taking true branch}}
150 array
[0] = getenv("TEMPDIR");
151 // expected-note@-1{{previous function call was here}}
154 // expected-note@-1{{Taking true branch}}
155 array
[1] = getenv("TMPDIR");
156 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
159 // expected-warning@-1{{dereferencing an invalid pointer}}
160 // expected-note@-2{{dereferencing an invalid pointer}}
163 void getenv_test9(void) {
165 p
= getenv("something");
167 p2
= getenv("something");
168 *p
; // no-warning: p does not point to getenv anymore
171 void getenv_test10(void) {
172 strcmp(getenv("VAR1"), getenv("VAR2"));
173 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
174 // expected-note@-2{{previous function call was here}}
175 // expected-warning@-3{{use of invalidated pointer 'getenv("VAR1")' in a function call}}
176 // expected-note@-4{{use of invalidated pointer 'getenv("VAR1")' in a function call}}
179 void dereference_pointer(char* a
) {
181 // expected-warning@-1{{dereferencing an invalid pointer}}
182 // expected-note@-2{{dereferencing an invalid pointer}}
185 void getenv_test11(void) {
186 char *p
= getenv("VAR");
187 // expected-note@-1{{previous function call was here}}
189 char *pp
= getenv("VAR2");
190 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
192 dereference_pointer(p
);
193 // expected-note@-1{{Calling 'dereference_pointer'}}
196 void getenv_test12(int flag1
, int flag2
) {
197 char *p
= getenv("VAR");
198 // expected-note@-1{{previous function call was here}}
201 // expected-note@-1{{Assuming 'flag1' is not equal to 0}}
202 // expected-note@-2{{Taking true branch}}
203 char *pp
= getenv("VAR2");
204 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
208 // expected-note@-1{{Assuming 'flag2' is not equal to 0}}
209 // expected-note@-2{{Taking true branch}}
211 // expected-warning@-1{{dereferencing an invalid pointer}}
212 // expected-note@-2{{dereferencing an invalid pointer}}
216 void setlocale_test1(void) {
218 p
= setlocale(0, "VAR");
221 p
= setlocale(0, "VAR2");
222 // expected-note@-1{{previous function call was here}}
225 p2
= setlocale(0, "VAR3");
226 // expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}
229 // expected-warning@-1{{dereferencing an invalid pointer}}
230 // expected-note@-2{{dereferencing an invalid pointer}}
233 void setlocale_test2(int flag
) {
235 p
= setlocale(0, "VAR");
238 p
= setlocale(0, "VAR2");
239 // expected-note@-1{{previous function call was here}}
243 // expected-note@-1{{Assuming 'flag' is not equal to 0}}
244 // expected-note@-2{{Taking true branch}}
245 p2
= setlocale(0, "VAR3");
246 // expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}
250 // expected-warning@-1{{dereferencing an invalid pointer}}
251 // expected-note@-2{{dereferencing an invalid pointer}}
254 void strerror_test1(void) {
261 // expected-note@-1{{previous function call was here}}
265 // expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}
268 // expected-warning@-1{{dereferencing an invalid pointer}}
269 // expected-note@-2{{dereferencing an invalid pointer}}
272 void strerror_test2(int errno
) {
279 // expected-note@-1{{previous function call was here}}
283 // expected-note@-1{{0 is not equal to 1}}
284 // expected-note@-2{{Taking false branch}}
291 // expected-note@-1{{Assuming 'errno' is not equal to 0}}
292 // expected-note@-2{{Taking true branch}}
293 p2
= strerror(errno
);
294 // expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}
298 // expected-warning@-1{{dereferencing an invalid pointer}}
299 // expected-note@-2{{dereferencing an invalid pointer}}
302 void asctime_test(void) {
306 char* p
= asctime(t
);
307 // expected-note@-1{{previous function call was here}}
308 char* pp
= asctime(tt
);
309 // expected-note@-1{{'asctime' call may invalidate the result of the previous 'asctime'}}
312 // expected-warning@-1{{dereferencing an invalid pointer}}
313 // expected-note@-2{{dereferencing an invalid pointer}}
316 void localeconv_test1(void) {
317 lconv
*lc1
= localeconv();
318 // expected-note@-1{{previous function call was here}}
319 lconv
*lc2
= localeconv();
320 // expected-note@-1{{'localeconv' call may invalidate the result of the previous 'localeconv'}}
323 // expected-warning@-1{{dereferencing an invalid pointer}}
324 // expected-note@-2{{dereferencing an invalid pointer}}
327 void localeconv_test2(void) {
328 // TODO: false negative
329 lconv
*lc1
= localeconv();
330 lconv
*lc2
= localeconv();