1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 2 // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 3 // RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 4 // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 5 // RUN: %clang_analyze_cc1 -DSUPPRESS_OUT_OF_BOUND -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring.BufferOverlap,alpha.unix.cstring.NotNullTerminated,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 6 7 //===----------------------------------------------------------------------=== 8 // Declarations 9 //===----------------------------------------------------------------------=== 10 11 // Some functions are so similar to each other that they follow the same code 12 // path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is 13 // defined, make sure to use the variants instead to make sure they are still 14 // checked by the analyzer. 15 16 // Some functions are implemented as builtins. These should be #defined as 17 // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined. 18 19 // Functions that have variants and are also available as builtins should be 20 // declared carefully! See memcpy() for an example. 21 22 #ifdef USE_BUILTINS 23 # define BUILTIN(f) __builtin_ ## f 24 #else /* USE_BUILTINS */ 25 # define BUILTIN(f) f 26 #endif /* USE_BUILTINS */ 27 28 #define NULL 0 29 typedef typeof(sizeof(int)) size_t; 30 31 void clang_analyzer_eval(int); 32 33 int scanf(const char *restrict format, ...); 34 void *malloc(size_t); 35 void free(void *); 36 37 //===----------------------------------------------------------------------=== 38 // strlen() 39 //===----------------------------------------------------------------------=== 40 41 #define strlen BUILTIN(strlen) 42 size_t strlen(const char *s); 43 44 void strlen_constant0() { 45 clang_analyzer_eval(strlen("123") == 3); // expected-warning{{TRUE}} 46 } 47 48 void strlen_constant1() { 49 const char *a = "123"; 50 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}} 51 } 52 53 void strlen_constant2(char x) { 54 char a[] = "123"; 55 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}} 56 57 a[0] = x; 58 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}} 59 } 60 61 size_t strlen_null() { 62 return strlen(0); // expected-warning{{Null pointer argument in call to string length function}} 63 } 64 65 size_t strlen_fn() { 66 return strlen((char*)&strlen_fn); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}} 67 } 68 69 size_t strlen_nonloc() { 70 label: 71 return strlen((char*)&&label); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}} 72 } 73 74 void strlen_subregion() { 75 struct two_strings { char a[2], b[2]; }; 76 extern void use_two_strings(struct two_strings *); 77 78 struct two_strings z; 79 use_two_strings(&z); 80 81 size_t a = strlen(z.a); 82 z.b[0] = 5; 83 size_t b = strlen(z.a); 84 if (a == 0) 85 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 86 87 use_two_strings(&z); 88 89 size_t c = strlen(z.a); 90 if (a == 0) 91 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 92 } 93 94 extern void use_string(char *); 95 void strlen_argument(char *x) { 96 size_t a = strlen(x); 97 size_t b = strlen(x); 98 if (a == 0) 99 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 100 101 use_string(x); 102 103 size_t c = strlen(x); 104 if (a == 0) 105 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 106 } 107 108 extern char global_str[]; 109 void strlen_global() { 110 size_t a = strlen(global_str); 111 size_t b = strlen(global_str); 112 if (a == 0) { 113 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 114 // Make sure clang_analyzer_eval does not invalidate globals. 115 clang_analyzer_eval(strlen(global_str) == 0); // expected-warning{{TRUE}} 116 } 117 118 // Call a function with unknown effects, which should invalidate globals. 119 use_string(0); 120 121 size_t c = strlen(global_str); 122 if (a == 0) 123 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 124 } 125 126 void strlen_indirect(char *x) { 127 size_t a = strlen(x); 128 char *p = x; 129 char **p2 = &p; 130 size_t b = strlen(x); 131 if (a == 0) 132 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 133 134 extern void use_string_ptr(char*const*); 135 use_string_ptr(p2); 136 137 size_t c = strlen(x); 138 if (a == 0) 139 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 140 } 141 142 void strlen_indirect2(char *x) { 143 size_t a = strlen(x); 144 char *p = x; 145 char **p2 = &p; 146 extern void use_string_ptr2(char**); 147 use_string_ptr2(p2); 148 149 size_t c = strlen(x); 150 if (a == 0) 151 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 152 } 153 154 void strlen_liveness(const char *x) { 155 if (strlen(x) < 5) 156 return; 157 clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}} 158 } 159 160 161 size_t strlenWrapper(const char *str) { 162 return strlen(str); 163 } 164 165 extern void invalidate(char *s); 166 167 void testStrlenCallee() { 168 char str[42]; 169 invalidate(str); 170 size_t lenBefore = strlenWrapper(str); 171 invalidate(str); 172 size_t lenAfter = strlenWrapper(str); 173 clang_analyzer_eval(lenBefore == lenAfter); // expected-warning{{UNKNOWN}} 174 } 175 176 177 //===----------------------------------------------------------------------=== 178 // strnlen() 179 //===----------------------------------------------------------------------=== 180 181 size_t strnlen(const char *s, size_t maxlen); 182 183 void strnlen_constant0() { 184 clang_analyzer_eval(strnlen("123", 10) == 3); // expected-warning{{TRUE}} 185 } 186 187 void strnlen_constant1() { 188 const char *a = "123"; 189 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}} 190 } 191 192 void strnlen_constant2(char x) { 193 char a[] = "123"; 194 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}} 195 a[0] = x; 196 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{UNKNOWN}} 197 } 198 199 void strnlen_constant4() { 200 clang_analyzer_eval(strnlen("123456", 3) == 3); // expected-warning{{TRUE}} 201 } 202 203 void strnlen_constant5() { 204 const char *a = "123456"; 205 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}} 206 } 207 208 void strnlen_constant6(char x) { 209 char a[] = "123456"; 210 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}} 211 a[0] = x; 212 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{UNKNOWN}} 213 } 214 215 size_t strnlen_null() { 216 return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length function}} 217 } 218 219 size_t strnlen_fn() { 220 return strnlen((char*)&strlen_fn, 3); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}} 221 } 222 223 size_t strnlen_nonloc() { 224 label: 225 return strnlen((char*)&&label, 3); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}} 226 } 227 228 void strnlen_zero() { 229 clang_analyzer_eval(strnlen("abc", 0) == 0); // expected-warning{{TRUE}} 230 clang_analyzer_eval(strnlen(NULL, 0) == 0); // expected-warning{{TRUE}} 231 } 232 233 size_t strnlen_compound_literal() { 234 // This used to crash because we don't model the string lengths of 235 // compound literals. 236 return strnlen((char[]) { 'a', 'b', 0 }, 1); 237 } 238 239 size_t strnlen_unknown_limit(float f) { 240 // This used to crash because we don't model the integer values of floats. 241 return strnlen("abc", (int)f); 242 } 243 244 void strnlen_is_not_strlen(char *x) { 245 clang_analyzer_eval(strnlen(x, 10) == strlen(x)); // expected-warning{{UNKNOWN}} 246 } 247 248 void strnlen_at_limit(char *x) { 249 size_t len = strnlen(x, 10); 250 clang_analyzer_eval(len <= 10); // expected-warning{{TRUE}} 251 clang_analyzer_eval(len == 10); // expected-warning{{UNKNOWN}} 252 clang_analyzer_eval(len < 10); // expected-warning{{UNKNOWN}} 253 } 254 255 void strnlen_at_actual(size_t limit) { 256 size_t len = strnlen("abc", limit); 257 clang_analyzer_eval(len <= 3); // expected-warning{{TRUE}} 258 // This is due to eager assertion in strnlen. 259 if (limit == 0) { 260 clang_analyzer_eval(len == 0); // expected-warning{{TRUE}} 261 } else { 262 clang_analyzer_eval(len == 3); // expected-warning{{UNKNOWN}} 263 clang_analyzer_eval(len < 3); // expected-warning{{UNKNOWN}} 264 } 265 } 266 267 //===----------------------------------------------------------------------=== 268 // strcpy() 269 //===----------------------------------------------------------------------=== 270 271 #ifdef VARIANT 272 273 #define __strcpy_chk BUILTIN(__strcpy_chk) 274 char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen); 275 276 #define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1) 277 278 #else /* VARIANT */ 279 280 #define strcpy BUILTIN(strcpy) 281 char *strcpy(char *restrict s1, const char *restrict s2); 282 283 #endif /* VARIANT */ 284 285 286 void strcpy_null_dst(char *x) { 287 strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}} 288 } 289 290 void strcpy_null_src(char *x) { 291 strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}} 292 } 293 294 void strcpy_fn(char *x) { 295 strcpy(x, (char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} 296 } 297 298 void strcpy_fn_const(char *x) { 299 strcpy(x, (const char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} 300 } 301 302 extern int globalInt; 303 void strcpy_effects(char *x, char *y) { 304 char a = x[0]; 305 if (globalInt != 42) 306 return; 307 308 clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}} 309 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}} 310 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} 311 clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}} 312 } 313 314 #ifndef SUPPRESS_OUT_OF_BOUND 315 void strcpy_overflow(char *y) { 316 char x[4]; 317 if (strlen(y) == 4) 318 strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} 319 } 320 #endif 321 322 void strcpy_no_overflow(char *y) { 323 char x[4]; 324 if (strlen(y) == 3) 325 strcpy(x, y); // no-warning 326 } 327 328 //===----------------------------------------------------------------------=== 329 // stpcpy() 330 //===----------------------------------------------------------------------=== 331 332 #ifdef VARIANT 333 334 #define __stpcpy_chk BUILTIN(__stpcpy_chk) 335 char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen); 336 337 #define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1) 338 339 #else /* VARIANT */ 340 341 #define stpcpy BUILTIN(stpcpy) 342 char *stpcpy(char *restrict s1, const char *restrict s2); 343 344 #endif /* VARIANT */ 345 346 347 void stpcpy_effect(char *x, char *y) { 348 char a = x[0]; 349 350 clang_analyzer_eval(stpcpy(x, y) == &x[strlen(y)]); // expected-warning{{TRUE}} 351 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}} 352 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} 353 } 354 355 #ifndef SUPPRESS_OUT_OF_BOUND 356 void stpcpy_overflow(char *y) { 357 char x[4]; 358 if (strlen(y) == 4) 359 stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} 360 } 361 #endif 362 363 void stpcpy_no_overflow(char *y) { 364 char x[4]; 365 if (strlen(y) == 3) 366 stpcpy(x, y); // no-warning 367 } 368 369 //===----------------------------------------------------------------------=== 370 // strcat() 371 //===----------------------------------------------------------------------=== 372 373 #ifdef VARIANT 374 375 #define __strcat_chk BUILTIN(__strcat_chk) 376 char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen); 377 378 #define strcat(a,b) __strcat_chk(a,b,(size_t)-1) 379 380 #else /* VARIANT */ 381 382 #define strcat BUILTIN(strcat) 383 char *strcat(char *restrict s1, const char *restrict s2); 384 385 #endif /* VARIANT */ 386 387 388 void strcat_null_dst(char *x) { 389 strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}} 390 } 391 392 void strcat_null_src(char *x) { 393 strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}} 394 } 395 396 void strcat_fn(char *x) { 397 strcat(x, (char*)&strcat_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcat_fn', which is not a null-terminated string}} 398 } 399 400 void strcat_effects(char *y) { 401 char x[8] = "123"; 402 size_t orig_len = strlen(x); 403 char a = x[0]; 404 405 if (strlen(y) != 4) 406 return; 407 408 clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}} 409 clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}} 410 } 411 412 #ifndef SUPPRESS_OUT_OF_BOUND 413 void strcat_overflow_0(char *y) { 414 char x[4] = "12"; 415 if (strlen(y) == 4) 416 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} 417 } 418 419 void strcat_overflow_1(char *y) { 420 char x[4] = "12"; 421 if (strlen(y) == 3) 422 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} 423 } 424 425 void strcat_overflow_2(char *y) { 426 char x[4] = "12"; 427 if (strlen(y) == 2) 428 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} 429 } 430 #endif 431 432 void strcat_no_overflow(char *y) { 433 char x[5] = "12"; 434 if (strlen(y) == 2) 435 strcat(x, y); // no-warning 436 } 437 438 void strcat_symbolic_dst_length(char *dst) { 439 strcat(dst, "1234"); 440 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 441 } 442 443 void strcat_symbolic_dst_length_taint(char *dst) { 444 scanf("%s", dst); // Taint data. 445 strcat(dst, "1234"); 446 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 447 } 448 449 void strcat_unknown_src_length(char *src, int offset) { 450 char dst[8] = "1234"; 451 strcat(dst, &src[offset]); 452 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 453 } 454 455 // There is no strcat_unknown_dst_length because if we can't get a symbolic 456 // length for the "before" strlen, we won't be able to set one for "after". 457 458 void strcat_too_big(char *dst, char *src) { 459 // We assume this can never actually happen, so we don't get a warning. 460 if (strlen(dst) != (((size_t)0) - 2)) 461 return; 462 if (strlen(src) != 2) 463 return; 464 strcat(dst, src); 465 } 466 467 468 //===----------------------------------------------------------------------=== 469 // strncpy() 470 //===----------------------------------------------------------------------=== 471 472 #ifdef VARIANT 473 474 #define __strncpy_chk BUILTIN(__strncpy_chk) 475 char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); 476 477 #define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1) 478 479 #else /* VARIANT */ 480 481 #define strncpy BUILTIN(strncpy) 482 char *strncpy(char *restrict s1, const char *restrict s2, size_t n); 483 484 #endif /* VARIANT */ 485 486 487 void strncpy_null_dst(char *x) { 488 strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}} 489 } 490 491 void strncpy_null_src(char *x) { 492 strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}} 493 } 494 495 void strncpy_fn(char *x) { 496 strncpy(x, (char*)&strcpy_fn, 5); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}} 497 } 498 499 void strncpy_effects(char *x, char *y) { 500 char a = x[0]; 501 502 clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}} 503 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}} 504 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} 505 } 506 507 #ifndef SUPPRESS_OUT_OF_BOUND 508 // Enabling the malloc checker enables some of the buffer-checking portions 509 // of the C-string checker. 510 void cstringchecker_bounds_nocrash() { 511 char *p = malloc(2); 512 strncpy(p, "AAA", sizeof("AAA")); // expected-warning {{Size argument is greater than the length of the destination buffer}} 513 free(p); 514 } 515 516 void strncpy_overflow(char *y) { 517 char x[4]; 518 if (strlen(y) == 4) 519 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} 520 } 521 522 void strncpy_no_overflow(char *y) { 523 char x[4]; 524 if (strlen(y) == 3) 525 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} 526 } 527 528 void strncpy_no_overflow2(char *y, int n) { 529 if (n <= 4) 530 return; 531 532 char x[4]; 533 if (strlen(y) == 3) 534 strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}} 535 } 536 #endif 537 538 void strncpy_truncate(char *y) { 539 char x[4]; 540 if (strlen(y) == 4) 541 strncpy(x, y, 3); // no-warning 542 } 543 544 void strncpy_no_truncate(char *y) { 545 char x[4]; 546 if (strlen(y) == 3) 547 strncpy(x, y, 3); // no-warning 548 } 549 550 void strncpy_exactly_matching_buffer(char *y) { 551 char x[4]; 552 strncpy(x, y, 4); // no-warning 553 554 // strncpy does not null-terminate, so we have no idea what the strlen is 555 // after this. 556 clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}} 557 } 558 559 void strncpy_zero(char *src) { 560 char dst[] = "123"; 561 strncpy(dst, src, 0); // no-warning 562 } 563 564 void strncpy_empty() { 565 char dst[] = "123"; 566 char src[] = ""; 567 strncpy(dst, src, 4); // no-warning 568 } 569 570 //===----------------------------------------------------------------------=== 571 // strncat() 572 //===----------------------------------------------------------------------=== 573 574 #ifdef VARIANT 575 576 #define __strncat_chk BUILTIN(__strncat_chk) 577 char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); 578 579 #define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1) 580 581 #else /* VARIANT */ 582 583 #define strncat BUILTIN(strncat) 584 char *strncat(char *restrict s1, const char *restrict s2, size_t n); 585 586 #endif /* VARIANT */ 587 588 589 void strncat_null_dst(char *x) { 590 strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}} 591 } 592 593 void strncat_null_src(char *x) { 594 strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}} 595 } 596 597 void strncat_fn(char *x) { 598 strncat(x, (char*)&strncat_fn, 4); // expected-warning{{Argument to string copy function is the address of the function 'strncat_fn', which is not a null-terminated string}} 599 } 600 601 void strncat_effects(char *y) { 602 char x[8] = "123"; 603 size_t orig_len = strlen(x); 604 char a = x[0]; 605 606 if (strlen(y) != 4) 607 return; 608 609 clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}} 610 clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}} 611 } 612 613 #ifndef SUPPRESS_OUT_OF_BOUND 614 void strncat_overflow_0(char *y) { 615 char x[4] = "12"; 616 if (strlen(y) == 4) 617 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 618 } 619 620 void strncat_overflow_1(char *y) { 621 char x[4] = "12"; 622 if (strlen(y) == 3) 623 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 624 } 625 626 void strncat_overflow_2(char *y) { 627 char x[4] = "12"; 628 if (strlen(y) == 2) 629 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 630 } 631 632 void strncat_overflow_3(char *y) { 633 char x[4] = "12"; 634 if (strlen(y) == 4) 635 strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 636 } 637 #endif 638 639 void strncat_no_overflow_1(char *y) { 640 char x[5] = "12"; 641 if (strlen(y) == 2) 642 strncat(x, y, strlen(y)); // no-warning 643 } 644 645 void strncat_no_overflow_2(char *y) { 646 char x[4] = "12"; 647 if (strlen(y) == 4) 648 strncat(x, y, 1); // no-warning 649 } 650 651 void strncat_symbolic_dst_length(char *dst) { 652 strncat(dst, "1234", 5); 653 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 654 } 655 656 #ifndef SUPPRESS_OUT_OF_BOUND 657 void strncat_symbolic_src_length(char *src) { 658 char dst[8] = "1234"; 659 strncat(dst, src, 3); 660 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 661 662 char dst2[8] = "1234"; 663 strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 664 } 665 666 void strncat_unknown_src_length(char *src, int offset) { 667 char dst[8] = "1234"; 668 strncat(dst, &src[offset], 3); 669 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 670 671 char dst2[8] = "1234"; 672 strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 673 } 674 #endif 675 676 // There is no strncat_unknown_dst_length because if we can't get a symbolic 677 // length for the "before" strlen, we won't be able to set one for "after". 678 679 void strncat_symbolic_limit(unsigned limit) { 680 char dst[6] = "1234"; 681 char src[] = "567"; 682 strncat(dst, src, limit); // no-warning 683 684 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 685 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 686 } 687 688 void strncat_unknown_limit(float limit) { 689 char dst[6] = "1234"; 690 char src[] = "567"; 691 strncat(dst, src, (size_t)limit); // no-warning 692 693 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 694 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 695 } 696 697 void strncat_too_big(char *dst, char *src) { 698 // We assume this will never actually happen, so we don't get a warning. 699 if (strlen(dst) != (((size_t)0) - 2)) 700 return; 701 if (strlen(src) != 2) 702 return; 703 strncat(dst, src, 2); 704 } 705 706 void strncat_zero(char *src) { 707 char dst[] = "123"; 708 strncat(dst, src, 0); // no-warning 709 } 710 711 void strncat_empty() { 712 char dst[8] = "123"; 713 char src[] = ""; 714 strncat(dst, src, 4); // no-warning 715 } 716 717 //===----------------------------------------------------------------------=== 718 // strcmp() 719 //===----------------------------------------------------------------------=== 720 721 #define strcmp BUILTIN(strcmp) 722 int strcmp(const char * s1, const char * s2); 723 724 void strcmp_check_modelling() { 725 char *x = "aa"; 726 char *y = "a"; 727 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 728 clang_analyzer_eval(strcmp(x, y) <= 0); // expected-warning{{FALSE}} 729 clang_analyzer_eval(strcmp(x, y) > 1); // expected-warning{{UNKNOWN}} 730 731 clang_analyzer_eval(strcmp(y, x) < 0); // expected-warning{{TRUE}} 732 clang_analyzer_eval(strcmp(y, x) >= 0); // expected-warning{{FALSE}} 733 clang_analyzer_eval(strcmp(y, x) < -1); // expected-warning{{UNKNOWN}} 734 } 735 736 void strcmp_constant0() { 737 clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}} 738 } 739 740 void strcmp_constant_and_var_0() { 741 char *x = "123"; 742 clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}} 743 } 744 745 void strcmp_constant_and_var_1() { 746 char *x = "123"; 747 clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}} 748 } 749 750 void strcmp_0() { 751 char *x = "123"; 752 char *y = "123"; 753 clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}} 754 } 755 756 void strcmp_1() { 757 char *x = "234"; 758 char *y = "123"; 759 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 760 } 761 762 void strcmp_2() { 763 char *x = "123"; 764 char *y = "234"; 765 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 766 } 767 768 void strcmp_null_0() { 769 char *x = NULL; 770 char *y = "123"; 771 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 772 } 773 774 void strcmp_null_1() { 775 char *x = "123"; 776 char *y = NULL; 777 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 778 } 779 780 void strcmp_diff_length_0() { 781 char *x = "12345"; 782 char *y = "234"; 783 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 784 } 785 786 void strcmp_diff_length_1() { 787 char *x = "123"; 788 char *y = "23456"; 789 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 790 } 791 792 void strcmp_diff_length_2() { 793 char *x = "12345"; 794 char *y = "123"; 795 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 796 } 797 798 void strcmp_diff_length_3() { 799 char *x = "123"; 800 char *y = "12345"; 801 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 802 } 803 804 void strcmp_embedded_null () { 805 clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}} 806 } 807 808 void strcmp_unknown_arg (char *unknown) { 809 clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}} 810 } 811 812 union argument { 813 char *f; 814 }; 815 816 void function_pointer_cast_helper(char **a) { 817 strcmp("Hi", *a); // PR24951 crash 818 } 819 820 void strcmp_union_function_pointer_cast(union argument a) { 821 void (*fPtr)(union argument *) = (void (*)(union argument *))function_pointer_cast_helper; 822 823 fPtr(&a); 824 } 825 826 //===----------------------------------------------------------------------=== 827 // strncmp() 828 //===----------------------------------------------------------------------=== 829 830 #define strncmp BUILTIN(strncmp) 831 int strncmp(const char *s1, const char *s2, size_t n); 832 833 void strncmp_check_modelling() { 834 char *x = "aa"; 835 char *y = "a"; 836 clang_analyzer_eval(strncmp(x, y, 2) > 0); // expected-warning{{TRUE}} 837 clang_analyzer_eval(strncmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 838 clang_analyzer_eval(strncmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 839 840 clang_analyzer_eval(strncmp(y, x, 2) < 0); // expected-warning{{TRUE}} 841 clang_analyzer_eval(strncmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 842 clang_analyzer_eval(strncmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 843 } 844 845 void strncmp_constant0() { 846 clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}} 847 } 848 849 void strncmp_constant_and_var_0() { 850 char *x = "123"; 851 clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}} 852 } 853 854 void strncmp_constant_and_var_1() { 855 char *x = "123"; 856 clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}} 857 } 858 859 void strncmp_0() { 860 char *x = "123"; 861 char *y = "123"; 862 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 863 } 864 865 void strncmp_1() { 866 char *x = "234"; 867 char *y = "123"; 868 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 869 } 870 871 void strncmp_2() { 872 char *x = "123"; 873 char *y = "234"; 874 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 875 } 876 877 void strncmp_null_0() { 878 char *x = NULL; 879 char *y = "123"; 880 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 881 } 882 883 void strncmp_null_1() { 884 char *x = "123"; 885 char *y = NULL; 886 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 887 } 888 889 void strncmp_diff_length_0() { 890 char *x = "12345"; 891 char *y = "234"; 892 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 893 } 894 895 void strncmp_diff_length_1() { 896 char *x = "123"; 897 char *y = "23456"; 898 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 899 } 900 901 void strncmp_diff_length_2() { 902 char *x = "12345"; 903 char *y = "123"; 904 clang_analyzer_eval(strncmp(x, y, 5) > 0); // expected-warning{{TRUE}} 905 } 906 907 void strncmp_diff_length_3() { 908 char *x = "123"; 909 char *y = "12345"; 910 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 911 } 912 913 void strncmp_diff_length_4() { 914 char *x = "123"; 915 char *y = "12345"; 916 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 917 } 918 919 void strncmp_diff_length_5() { 920 char *x = "012"; 921 char *y = "12345"; 922 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 923 } 924 925 void strncmp_diff_length_6() { 926 char *x = "234"; 927 char *y = "12345"; 928 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 929 } 930 931 void strncmp_embedded_null () { 932 clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 933 } 934 935 //===----------------------------------------------------------------------=== 936 // strcasecmp() 937 //===----------------------------------------------------------------------=== 938 939 #define strcasecmp BUILTIN(strcasecmp) 940 int strcasecmp(const char *s1, const char *s2); 941 942 void strcasecmp_check_modelling() { 943 char *x = "aa"; 944 char *y = "a"; 945 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 946 clang_analyzer_eval(strcasecmp(x, y) <= 0); // expected-warning{{FALSE}} 947 clang_analyzer_eval(strcasecmp(x, y) > 1); // expected-warning{{UNKNOWN}} 948 949 clang_analyzer_eval(strcasecmp(y, x) < 0); // expected-warning{{TRUE}} 950 clang_analyzer_eval(strcasecmp(y, x) >= 0); // expected-warning{{FALSE}} 951 clang_analyzer_eval(strcasecmp(y, x) < -1); // expected-warning{{UNKNOWN}} 952 } 953 954 void strcasecmp_constant0() { 955 clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}} 956 } 957 958 void strcasecmp_constant_and_var_0() { 959 char *x = "abc"; 960 clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}} 961 } 962 963 void strcasecmp_constant_and_var_1() { 964 char *x = "abc"; 965 clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}} 966 } 967 968 void strcasecmp_0() { 969 char *x = "abc"; 970 char *y = "Abc"; 971 clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}} 972 } 973 974 void strcasecmp_1() { 975 char *x = "Bcd"; 976 char *y = "abc"; 977 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 978 } 979 980 void strcasecmp_2() { 981 char *x = "abc"; 982 char *y = "Bcd"; 983 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 984 } 985 986 void strcasecmp_null_0() { 987 char *x = NULL; 988 char *y = "123"; 989 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 990 } 991 992 void strcasecmp_null_1() { 993 char *x = "123"; 994 char *y = NULL; 995 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 996 } 997 998 void strcasecmp_diff_length_0() { 999 char *x = "abcde"; 1000 char *y = "aBd"; 1001 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1002 } 1003 1004 void strcasecmp_diff_length_1() { 1005 char *x = "abc"; 1006 char *y = "aBdef"; 1007 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1008 } 1009 1010 void strcasecmp_diff_length_2() { 1011 char *x = "aBcDe"; 1012 char *y = "abc"; 1013 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 1014 } 1015 1016 void strcasecmp_diff_length_3() { 1017 char *x = "aBc"; 1018 char *y = "abcde"; 1019 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1020 } 1021 1022 void strcasecmp_embedded_null () { 1023 clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}} 1024 } 1025 1026 //===----------------------------------------------------------------------=== 1027 // strncasecmp() 1028 //===----------------------------------------------------------------------=== 1029 1030 #define strncasecmp BUILTIN(strncasecmp) 1031 int strncasecmp(const char *s1, const char *s2, size_t n); 1032 1033 void strncasecmp_check_modelling() { 1034 char *x = "aa"; 1035 char *y = "a"; 1036 clang_analyzer_eval(strncasecmp(x, y, 2) > 0); // expected-warning{{TRUE}} 1037 clang_analyzer_eval(strncasecmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 1038 clang_analyzer_eval(strncasecmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 1039 1040 clang_analyzer_eval(strncasecmp(y, x, 2) < 0); // expected-warning{{TRUE}} 1041 clang_analyzer_eval(strncasecmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 1042 clang_analyzer_eval(strncasecmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 1043 } 1044 1045 void strncasecmp_constant0() { 1046 clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}} 1047 } 1048 1049 void strncasecmp_constant_and_var_0() { 1050 char *x = "abc"; 1051 clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}} 1052 } 1053 1054 void strncasecmp_constant_and_var_1() { 1055 char *x = "abc"; 1056 clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}} 1057 } 1058 1059 void strncasecmp_0() { 1060 char *x = "abc"; 1061 char *y = "Abc"; 1062 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1063 } 1064 1065 void strncasecmp_1() { 1066 char *x = "Bcd"; 1067 char *y = "abc"; 1068 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1069 } 1070 1071 void strncasecmp_2() { 1072 char *x = "abc"; 1073 char *y = "Bcd"; 1074 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1075 } 1076 1077 void strncasecmp_null_0() { 1078 char *x = NULL; 1079 char *y = "123"; 1080 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 1081 } 1082 1083 void strncasecmp_null_1() { 1084 char *x = "123"; 1085 char *y = NULL; 1086 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 1087 } 1088 1089 void strncasecmp_diff_length_0() { 1090 char *x = "abcde"; 1091 char *y = "aBd"; 1092 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1093 } 1094 1095 void strncasecmp_diff_length_1() { 1096 char *x = "abc"; 1097 char *y = "aBdef"; 1098 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1099 } 1100 1101 void strncasecmp_diff_length_2() { 1102 char *x = "aBcDe"; 1103 char *y = "abc"; 1104 clang_analyzer_eval(strncasecmp(x, y, 5) > 0); // expected-warning{{TRUE}} 1105 } 1106 1107 void strncasecmp_diff_length_3() { 1108 char *x = "aBc"; 1109 char *y = "abcde"; 1110 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1111 } 1112 1113 void strncasecmp_diff_length_4() { 1114 char *x = "abcde"; 1115 char *y = "aBc"; 1116 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1117 } 1118 1119 void strncasecmp_diff_length_5() { 1120 char *x = "abcde"; 1121 char *y = "aBd"; 1122 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1123 } 1124 1125 void strncasecmp_diff_length_6() { 1126 char *x = "aBDe"; 1127 char *y = "abc"; 1128 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1129 } 1130 1131 void strncasecmp_embedded_null () { 1132 clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 1133 } 1134 1135 //===----------------------------------------------------------------------=== 1136 // strsep() 1137 //===----------------------------------------------------------------------=== 1138 1139 char *strsep(char **stringp, const char *delim); 1140 1141 void strsep_null_delim(char *s) { 1142 strsep(&s, NULL); // expected-warning{{Null pointer argument in call to strsep()}} 1143 } 1144 1145 void strsep_null_search() { 1146 strsep(NULL, ""); // expected-warning{{Null pointer argument in call to strsep()}} 1147 } 1148 1149 void strsep_return_original_pointer(char *s) { 1150 char *original = s; 1151 char *result = strsep(&s, ""); // no-warning 1152 clang_analyzer_eval(original == result); // expected-warning{{TRUE}} 1153 } 1154 1155 void strsep_null_string() { 1156 char *s = NULL; 1157 char *result = strsep(&s, ""); // no-warning 1158 clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}} 1159 } 1160 1161 void strsep_changes_input_pointer(char *s) { 1162 char *original = s; 1163 strsep(&s, ""); // no-warning 1164 clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}} 1165 clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}} 1166 1167 // Check that the value is symbolic. 1168 if (s == NULL) { 1169 clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}} 1170 } 1171 } 1172 1173 void strsep_changes_input_string() { 1174 char str[] = "abc"; 1175 1176 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}} 1177 1178 char *s = str; 1179 strsep(&s, "b"); // no-warning 1180 1181 // The real strsep will change the first delimiter it finds into a NUL 1182 // character. For now, we just model the invalidation. 1183 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}} 1184 } 1185 1186 //===----------------------------------------------------------------------=== 1187 // memset() / explicit_bzero() / bzero() 1188 //===----------------------------------------------------------------------=== 1189 1190 void *memset(void *dest, int ch, size_t count); 1191 1192 void bzero(void *dst, size_t count); 1193 void explicit_bzero(void *dest, size_t count); 1194 1195 void *malloc(size_t size); 1196 void free(void *); 1197 1198 void memset1_char_array_null() { 1199 char str[] = "abcd"; 1200 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1201 memset(str, '\0', 2); 1202 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1203 } 1204 1205 void memset2_char_array_null() { 1206 char str[] = "abcd"; 1207 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1208 memset(str, '\0', strlen(str) + 1); 1209 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1210 clang_analyzer_eval(str[2] == 0); // expected-warning{{TRUE}} 1211 } 1212 1213 void memset3_char_malloc_null() { 1214 char *str = (char *)malloc(10 * sizeof(char)); 1215 memset(str + 1, '\0', 8); 1216 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1217 free(str); 1218 } 1219 1220 void memset4_char_malloc_null() { 1221 char *str = (char *)malloc(10 * sizeof(char)); 1222 //void *str = malloc(10 * sizeof(char)); 1223 memset(str, '\0', 10); 1224 clang_analyzer_eval(str[1] == 0); // expected-warning{{TRUE}} 1225 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1226 free(str); 1227 } 1228 1229 #ifdef SUPPRESS_OUT_OF_BOUND 1230 void memset5_char_malloc_overflow_null() { 1231 char *str = (char *)malloc(10 * sizeof(char)); 1232 memset(str, '\0', 12); 1233 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1234 free(str); 1235 } 1236 #endif 1237 1238 void memset6_char_array_nonnull() { 1239 char str[] = "abcd"; 1240 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1241 memset(str, '0', 2); 1242 clang_analyzer_eval(str[0] == 'a'); // expected-warning{{UNKNOWN}} 1243 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{UNKNOWN}} 1244 } 1245 1246 #ifdef SUPPRESS_OUT_OF_BOUND 1247 void memset8_char_array_nonnull() { 1248 char str[5] = "abcd"; 1249 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1250 memset(str, '0', 10); 1251 clang_analyzer_eval(str[0] != '0'); // expected-warning{{UNKNOWN}} 1252 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1253 clang_analyzer_eval(strlen(str) < 10); // expected-warning{{FALSE}} 1254 } 1255 #endif 1256 1257 struct POD_memset { 1258 int num; 1259 char c; 1260 }; 1261 1262 void memset10_struct() { 1263 struct POD_memset pod; 1264 char *str = (char *)&pod; 1265 pod.num = 1; 1266 pod.c = 1; 1267 clang_analyzer_eval(pod.num == 0); // expected-warning{{FALSE}} 1268 memset(str, 0, sizeof(struct POD_memset)); 1269 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1270 } 1271 1272 #ifdef SUPPRESS_OUT_OF_BOUND 1273 void memset11_struct_field() { 1274 struct POD_memset pod; 1275 pod.num = 1; 1276 pod.c = '1'; 1277 memset(&pod.num, 0, sizeof(struct POD_memset)); 1278 1279 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1280 clang_analyzer_eval(pod.c == '\0'); // expected-warning{{TRUE}} 1281 } 1282 1283 void memset12_struct_field() { 1284 struct POD_memset pod; 1285 pod.num = 1; 1286 pod.c = '1'; 1287 memset(&pod.c, 0, sizeof(struct POD_memset)); 1288 clang_analyzer_eval(pod.num == 0); // expected-warning{{UNKNOWN}} 1289 clang_analyzer_eval(pod.c == 0); // expected-warning{{UNKNOWN}} 1290 } 1291 1292 union U_memset { 1293 int i; 1294 double d; 1295 char c; 1296 }; 1297 1298 void memset13_union_field() { 1299 union U_memset u; 1300 u.i = 5; 1301 memset(&u.i, '\0', sizeof(union U_memset)); 1302 // Note: This should be TRUE, analyzer can't handle union perfectly now. 1303 clang_analyzer_eval(u.d == 0); // expected-warning{{UNKNOWN}} 1304 } 1305 #endif 1306 1307 void memset14_region_cast() { 1308 char *str = (char *)malloc(10 * sizeof(int)); 1309 int *array = (int *)str; 1310 memset(array, 0, 10 * sizeof(int)); 1311 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{TRUE}} 1312 clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}} 1313 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1314 free(str); 1315 } 1316 1317 void memset15_region_cast() { 1318 char *str = (char *)malloc(10 * sizeof(int)); 1319 int *array = (int *)str; 1320 memset(array, 0, 5 * sizeof(int)); 1321 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{UNKNOWN}} 1322 clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}} 1323 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1324 free(str); 1325 } 1326 1327 int memset20_scalar() { 1328 int *x = malloc(sizeof(int)); 1329 *x = 10; 1330 memset(x, 0, sizeof(int)); 1331 int num = 1 / *x; // expected-warning{{Division by zero}} 1332 free(x); 1333 return num; 1334 } 1335 1336 int memset21_scalar() { 1337 int *x = malloc(sizeof(int)); 1338 memset(x, 0, 1); 1339 int num = 1 / *x; 1340 free(x); 1341 return num; 1342 } 1343 1344 void memset22_array() { 1345 int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 1346 clang_analyzer_eval(array[1] == 2); // expected-warning{{TRUE}} 1347 memset(array, 0, sizeof(array)); 1348 clang_analyzer_eval(array[1] == 0); // expected-warning{{TRUE}} 1349 } 1350 1351 void memset23_array_pod_object() { 1352 struct POD_memset array[10]; 1353 array[1].num = 10; 1354 array[1].c = 'c'; 1355 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1356 memset(&array[1], 0, sizeof(struct POD_memset)); 1357 clang_analyzer_eval(array[1].num == 0); // expected-warning{{UNKNOWN}} 1358 } 1359 1360 void memset24_array_pod_object() { 1361 struct POD_memset array[10]; 1362 array[1].num = 10; 1363 array[1].c = 'c'; 1364 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1365 memset(array, 0, sizeof(array)); 1366 clang_analyzer_eval(array[1].num == 0); // expected-warning{{TRUE}} 1367 } 1368 1369 void memset25_symbol(char c) { 1370 char array[10] = {1}; 1371 if (c != 0) 1372 return; 1373 1374 memset(array, c, 10); 1375 1376 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1377 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1378 } 1379 1380 void memset26_upper_UCHAR_MAX() { 1381 char array[10] = {1}; 1382 1383 memset(array, 1024, 10); 1384 1385 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1386 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1387 } 1388 1389 void bzero1_null() { 1390 char *a = NULL; 1391 1392 bzero(a, 10); // expected-warning{{Null pointer argument in call to memory clearance function}} 1393 } 1394 1395 void bzero2_char_array_null() { 1396 char str[] = "abcd"; 1397 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1398 bzero(str, 2); 1399 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1400 } 1401 1402 void bzero3_char_ptr_null() { 1403 char *str = "abcd"; 1404 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1405 bzero(str + 2, 2); 1406 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{FALSE}} 1407 } 1408 1409 void explicit_bzero1_null() { 1410 char *a = NULL; 1411 1412 explicit_bzero(a, 10); // expected-warning{{Null pointer argument in call to memory clearance function}} 1413 } 1414 1415 void explicit_bzero2_clear_mypassword() { 1416 char passwd[7] = "passwd"; 1417 1418 explicit_bzero(passwd, sizeof(passwd)); // no-warning 1419 1420 clang_analyzer_eval(strlen(passwd) == 0); // expected-warning{{TRUE}} 1421 clang_analyzer_eval(passwd[0] == '\0'); // expected-warning{{TRUE}} 1422 } 1423 1424 void explicit_bzero3_out_ofbound() { 1425 char *privkey = (char *)malloc(7); 1426 const char newprivkey[10] = "mysafekey"; 1427 1428 strcpy(privkey, "random"); 1429 explicit_bzero(privkey, sizeof(newprivkey)); 1430 #ifndef SUPPRESS_OUT_OF_BOUND 1431 // expected-warning@-2 {{Memory clearance function accesses out-of-bound array element}} 1432 #endif 1433 clang_analyzer_eval(privkey[0] == '\0'); 1434 #ifdef SUPPRESS_OUT_OF_BOUND 1435 // expected-warning@-2 {{UNKNOWN}} 1436 #endif 1437 free(privkey); 1438 } 1439 1440 //===----------------------------------------------------------------------=== 1441 // FIXMEs 1442 //===----------------------------------------------------------------------=== 1443 1444 // The analyzer_eval call below should evaluate to true. We are being too 1445 // aggressive in marking the (length of) src symbol dead. The length of dst 1446 // depends on src. This could be explicitly specified in the checker or the 1447 // logic for handling MetadataSymbol in SymbolManager needs to change. 1448 void strcat_symbolic_src_length(char *src) { 1449 char dst[8] = "1234"; 1450 strcat(dst, src); 1451 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}} 1452 } 1453 1454 1455 // The analyzer_eval call below should evaluate to true. Most likely the same 1456 // issue as the test above. 1457 void strncpy_exactly_matching_buffer2(char *y) { 1458 if (strlen(y) >= 4) 1459 return; 1460 1461 char x[4]; 1462 strncpy(x, y, 4); // no-warning 1463 1464 // This time, we know that y fits in x anyway. 1465 clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}} 1466 } 1467 1468 void memset7_char_array_nonnull() { 1469 char str[5] = "abcd"; 1470 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1471 memset(str, '0', 5); 1472 // FIXME: This should be TRUE. 1473 clang_analyzer_eval(str[0] == '0'); // expected-warning{{UNKNOWN}} 1474 clang_analyzer_eval(strlen(str) >= 5); // expected-warning{{TRUE}} 1475 } 1476 1477 void memset16_region_cast() { 1478 char *str = (char *)malloc(10 * sizeof(int)); 1479 int *array = (int *)str; 1480 memset(array, '0', 10 * sizeof(int)); 1481 // FIXME: This should be TRUE. 1482 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1483 clang_analyzer_eval(strlen((char *)array) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1484 clang_analyzer_eval(strlen(str) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1485 free(str); 1486 } 1487 1488 #ifdef SUPPRESS_OUT_OF_BOUND 1489 void memset17_region_cast() { 1490 char *str = (char *)malloc(10 * sizeof(int)); 1491 int *array = (int *)str; 1492 memset(array, '0', 12 * sizeof(int)); 1493 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1494 clang_analyzer_eval(strlen((char *)array) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1495 clang_analyzer_eval(strlen(str) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1496 free(str); 1497 } 1498 1499 void memset18_memset_multiple_times() { 1500 char *str = (char *)malloc(10 * sizeof(char)); 1501 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1502 1503 memset(str + 2, '\0', 10 * sizeof(char)); 1504 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1505 clang_analyzer_eval(str[1] == '\0'); // expected-warning{{UNKNOWN}} 1506 1507 memset(str, '0', 10 * sizeof(char)); 1508 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1509 // FIXME: This should be TRUE. 1510 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1511 1512 free(str); 1513 } 1514 1515 void memset19_memset_multiple_times() { 1516 char *str = (char *)malloc(10 * sizeof(char)); 1517 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1518 1519 memset(str, '0', 10 * sizeof(char)); 1520 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1521 // FIXME: This should be TRUE. 1522 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1523 1524 memset(str + 2, '\0', 10 * sizeof(char)); 1525 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{UNKNOWN}} 1526 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1527 1528 free(str); 1529 } 1530 #endif 1531 1532 // The analyzer does not support binding a symbol with default binding. 1533 void memset27_symbol(char c) { 1534 char array[10] = {0}; 1535 if (c < 10) 1536 return; 1537 1538 memset(array, c, 10); 1539 1540 clang_analyzer_eval(strlen(array) >= 10); // expected-warning{{TRUE}} 1541 // FIXME: This should be TRUE. 1542 clang_analyzer_eval(array[4] >= 10); // expected-warning{{UNKNOWN}} 1543 } 1544 1545 void memset28() { 1546 short x; 1547 memset(&x, 1, sizeof(short)); 1548 // This should be true. 1549 clang_analyzer_eval(x == 0x101); // expected-warning{{UNKNOWN}} 1550 } 1551