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 #ifndef VARIANT 521 // expected-warning@-2{{size argument is too large; destination buffer has size 4, but size argument is 5}} 522 #endif 523 } 524 525 void strncpy_no_overflow(char *y) { 526 char x[4]; 527 if (strlen(y) == 3) 528 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} 529 #ifndef VARIANT 530 // expected-warning@-2{{size argument is too large; destination buffer has size 4, but size argument is 5}} 531 #endif 532 } 533 534 void strncpy_no_overflow2(char *y, int n) { 535 if (n <= 4) 536 return; 537 538 char x[4]; 539 if (strlen(y) == 3) 540 strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}} 541 } 542 #endif 543 544 void strncpy_truncate(char *y) { 545 char x[4]; 546 if (strlen(y) == 4) 547 strncpy(x, y, 3); // no-warning 548 } 549 550 void strncpy_no_truncate(char *y) { 551 char x[4]; 552 if (strlen(y) == 3) 553 strncpy(x, y, 3); // no-warning 554 } 555 556 void strncpy_exactly_matching_buffer(char *y) { 557 char x[4]; 558 strncpy(x, y, 4); // no-warning 559 560 // strncpy does not null-terminate, so we have no idea what the strlen is 561 // after this. 562 clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}} 563 } 564 565 void strncpy_zero(char *src) { 566 char dst[] = "123"; 567 strncpy(dst, src, 0); // no-warning 568 } 569 570 void strncpy_empty() { 571 char dst[] = "123"; 572 char src[] = ""; 573 strncpy(dst, src, 4); // no-warning 574 } 575 576 //===----------------------------------------------------------------------=== 577 // strncat() 578 //===----------------------------------------------------------------------=== 579 580 #ifdef VARIANT 581 582 #define __strncat_chk BUILTIN(__strncat_chk) 583 char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); 584 585 #define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1) 586 587 #else /* VARIANT */ 588 589 #define strncat BUILTIN(strncat) 590 char *strncat(char *restrict s1, const char *restrict s2, size_t n); 591 592 #endif /* VARIANT */ 593 594 595 void strncat_null_dst(char *x) { 596 strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}} 597 } 598 599 void strncat_null_src(char *x) { 600 strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}} 601 } 602 603 void strncat_fn(char *x) { 604 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}} 605 } 606 607 void strncat_effects(char *y) { 608 char x[8] = "123"; 609 size_t orig_len = strlen(x); 610 char a = x[0]; 611 612 if (strlen(y) != 4) 613 return; 614 615 clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}} 616 clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}} 617 } 618 619 #ifndef SUPPRESS_OUT_OF_BOUND 620 void strncat_overflow_0(char *y) { 621 char x[4] = "12"; 622 if (strlen(y) == 4) 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_1(char *y) { 627 char x[4] = "12"; 628 if (strlen(y) == 3) 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_2(char *y) { 633 char x[4] = "12"; 634 if (strlen(y) == 2) 635 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 636 } 637 638 void strncat_overflow_3(char *y) { 639 char x[4] = "12"; 640 if (strlen(y) == 4) 641 strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 642 } 643 #endif 644 645 void strncat_no_overflow_1(char *y) { 646 char x[5] = "12"; 647 if (strlen(y) == 2) 648 strncat(x, y, strlen(y)); // no-warning 649 } 650 651 void strncat_no_overflow_2(char *y) { 652 char x[4] = "12"; 653 if (strlen(y) == 4) 654 strncat(x, y, 1); // no-warning 655 } 656 657 void strncat_symbolic_dst_length(char *dst) { 658 strncat(dst, "1234", 5); 659 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 660 } 661 662 #ifndef SUPPRESS_OUT_OF_BOUND 663 void strncat_symbolic_src_length(char *src) { 664 char dst[8] = "1234"; 665 strncat(dst, src, 3); 666 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 667 668 char dst2[8] = "1234"; 669 strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 670 } 671 672 void strncat_unknown_src_length(char *src, int offset) { 673 char dst[8] = "1234"; 674 strncat(dst, &src[offset], 3); 675 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 676 677 char dst2[8] = "1234"; 678 strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 679 } 680 #endif 681 682 // There is no strncat_unknown_dst_length because if we can't get a symbolic 683 // length for the "before" strlen, we won't be able to set one for "after". 684 685 void strncat_symbolic_limit(unsigned limit) { 686 char dst[6] = "1234"; 687 char src[] = "567"; 688 strncat(dst, src, limit); // no-warning 689 690 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 691 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 692 } 693 694 void strncat_unknown_limit(float limit) { 695 char dst[6] = "1234"; 696 char src[] = "567"; 697 strncat(dst, src, (size_t)limit); // no-warning 698 699 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 700 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 701 } 702 703 void strncat_too_big(char *dst, char *src) { 704 // We assume this will never actually happen, so we don't get a warning. 705 if (strlen(dst) != (((size_t)0) - 2)) 706 return; 707 if (strlen(src) != 2) 708 return; 709 strncat(dst, src, 2); 710 } 711 712 void strncat_zero(char *src) { 713 char dst[] = "123"; 714 strncat(dst, src, 0); // no-warning 715 } 716 717 void strncat_empty() { 718 char dst[8] = "123"; 719 char src[] = ""; 720 strncat(dst, src, 4); // no-warning 721 } 722 723 //===----------------------------------------------------------------------=== 724 // strcmp() 725 //===----------------------------------------------------------------------=== 726 727 #define strcmp BUILTIN(strcmp) 728 int strcmp(const char * s1, const char * s2); 729 730 void strcmp_check_modelling() { 731 char *x = "aa"; 732 char *y = "a"; 733 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 734 clang_analyzer_eval(strcmp(x, y) <= 0); // expected-warning{{FALSE}} 735 clang_analyzer_eval(strcmp(x, y) > 1); // expected-warning{{UNKNOWN}} 736 737 clang_analyzer_eval(strcmp(y, x) < 0); // expected-warning{{TRUE}} 738 clang_analyzer_eval(strcmp(y, x) >= 0); // expected-warning{{FALSE}} 739 clang_analyzer_eval(strcmp(y, x) < -1); // expected-warning{{UNKNOWN}} 740 } 741 742 void strcmp_constant0() { 743 clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}} 744 } 745 746 void strcmp_constant_and_var_0() { 747 char *x = "123"; 748 clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}} 749 } 750 751 void strcmp_constant_and_var_1() { 752 char *x = "123"; 753 clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}} 754 } 755 756 void strcmp_0() { 757 char *x = "123"; 758 char *y = "123"; 759 clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}} 760 } 761 762 void strcmp_1() { 763 char *x = "234"; 764 char *y = "123"; 765 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 766 } 767 768 void strcmp_2() { 769 char *x = "123"; 770 char *y = "234"; 771 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 772 } 773 774 void strcmp_null_0() { 775 char *x = NULL; 776 char *y = "123"; 777 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 778 } 779 780 void strcmp_null_1() { 781 char *x = "123"; 782 char *y = NULL; 783 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 784 } 785 786 void strcmp_diff_length_0() { 787 char *x = "12345"; 788 char *y = "234"; 789 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 790 } 791 792 void strcmp_diff_length_1() { 793 char *x = "123"; 794 char *y = "23456"; 795 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 796 } 797 798 void strcmp_diff_length_2() { 799 char *x = "12345"; 800 char *y = "123"; 801 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 802 } 803 804 void strcmp_diff_length_3() { 805 char *x = "123"; 806 char *y = "12345"; 807 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 808 } 809 810 void strcmp_embedded_null () { 811 clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}} 812 } 813 814 void strcmp_unknown_arg (char *unknown) { 815 clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}} 816 } 817 818 union argument { 819 char *f; 820 }; 821 822 void function_pointer_cast_helper(char **a) { 823 strcmp("Hi", *a); // PR24951 crash 824 } 825 826 void strcmp_union_function_pointer_cast(union argument a) { 827 void (*fPtr)(union argument *) = (void (*)(union argument *))function_pointer_cast_helper; 828 829 fPtr(&a); 830 } 831 832 //===----------------------------------------------------------------------=== 833 // strncmp() 834 //===----------------------------------------------------------------------=== 835 836 #define strncmp BUILTIN(strncmp) 837 int strncmp(const char *s1, const char *s2, size_t n); 838 839 void strncmp_check_modelling() { 840 char *x = "aa"; 841 char *y = "a"; 842 clang_analyzer_eval(strncmp(x, y, 2) > 0); // expected-warning{{TRUE}} 843 clang_analyzer_eval(strncmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 844 clang_analyzer_eval(strncmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 845 846 clang_analyzer_eval(strncmp(y, x, 2) < 0); // expected-warning{{TRUE}} 847 clang_analyzer_eval(strncmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 848 clang_analyzer_eval(strncmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 849 } 850 851 void strncmp_constant0() { 852 clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}} 853 } 854 855 void strncmp_constant_and_var_0() { 856 char *x = "123"; 857 clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}} 858 } 859 860 void strncmp_constant_and_var_1() { 861 char *x = "123"; 862 clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}} 863 } 864 865 void strncmp_0() { 866 char *x = "123"; 867 char *y = "123"; 868 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 869 } 870 871 void strncmp_1() { 872 char *x = "234"; 873 char *y = "123"; 874 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 875 } 876 877 void strncmp_2() { 878 char *x = "123"; 879 char *y = "234"; 880 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 881 } 882 883 void strncmp_null_0() { 884 char *x = NULL; 885 char *y = "123"; 886 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 887 } 888 889 void strncmp_null_1() { 890 char *x = "123"; 891 char *y = NULL; 892 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 893 } 894 895 void strncmp_diff_length_0() { 896 char *x = "12345"; 897 char *y = "234"; 898 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 899 } 900 901 void strncmp_diff_length_1() { 902 char *x = "123"; 903 char *y = "23456"; 904 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 905 } 906 907 void strncmp_diff_length_2() { 908 char *x = "12345"; 909 char *y = "123"; 910 clang_analyzer_eval(strncmp(x, y, 5) > 0); // expected-warning{{TRUE}} 911 } 912 913 void strncmp_diff_length_3() { 914 char *x = "123"; 915 char *y = "12345"; 916 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 917 } 918 919 void strncmp_diff_length_4() { 920 char *x = "123"; 921 char *y = "12345"; 922 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 923 } 924 925 void strncmp_diff_length_5() { 926 char *x = "012"; 927 char *y = "12345"; 928 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 929 } 930 931 void strncmp_diff_length_6() { 932 char *x = "234"; 933 char *y = "12345"; 934 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 935 } 936 937 void strncmp_embedded_null () { 938 clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 939 } 940 941 //===----------------------------------------------------------------------=== 942 // strcasecmp() 943 //===----------------------------------------------------------------------=== 944 945 #define strcasecmp BUILTIN(strcasecmp) 946 int strcasecmp(const char *s1, const char *s2); 947 948 void strcasecmp_check_modelling() { 949 char *x = "aa"; 950 char *y = "a"; 951 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 952 clang_analyzer_eval(strcasecmp(x, y) <= 0); // expected-warning{{FALSE}} 953 clang_analyzer_eval(strcasecmp(x, y) > 1); // expected-warning{{UNKNOWN}} 954 955 clang_analyzer_eval(strcasecmp(y, x) < 0); // expected-warning{{TRUE}} 956 clang_analyzer_eval(strcasecmp(y, x) >= 0); // expected-warning{{FALSE}} 957 clang_analyzer_eval(strcasecmp(y, x) < -1); // expected-warning{{UNKNOWN}} 958 } 959 960 void strcasecmp_constant0() { 961 clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}} 962 } 963 964 void strcasecmp_constant_and_var_0() { 965 char *x = "abc"; 966 clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}} 967 } 968 969 void strcasecmp_constant_and_var_1() { 970 char *x = "abc"; 971 clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}} 972 } 973 974 void strcasecmp_0() { 975 char *x = "abc"; 976 char *y = "Abc"; 977 clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}} 978 } 979 980 void strcasecmp_1() { 981 char *x = "Bcd"; 982 char *y = "abc"; 983 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 984 } 985 986 void strcasecmp_2() { 987 char *x = "abc"; 988 char *y = "Bcd"; 989 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 990 } 991 992 void strcasecmp_null_0() { 993 char *x = NULL; 994 char *y = "123"; 995 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 996 } 997 998 void strcasecmp_null_1() { 999 char *x = "123"; 1000 char *y = NULL; 1001 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 1002 } 1003 1004 void strcasecmp_diff_length_0() { 1005 char *x = "abcde"; 1006 char *y = "aBd"; 1007 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1008 } 1009 1010 void strcasecmp_diff_length_1() { 1011 char *x = "abc"; 1012 char *y = "aBdef"; 1013 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1014 } 1015 1016 void strcasecmp_diff_length_2() { 1017 char *x = "aBcDe"; 1018 char *y = "abc"; 1019 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 1020 } 1021 1022 void strcasecmp_diff_length_3() { 1023 char *x = "aBc"; 1024 char *y = "abcde"; 1025 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1026 } 1027 1028 void strcasecmp_embedded_null () { 1029 clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}} 1030 } 1031 1032 //===----------------------------------------------------------------------=== 1033 // strncasecmp() 1034 //===----------------------------------------------------------------------=== 1035 1036 #define strncasecmp BUILTIN(strncasecmp) 1037 int strncasecmp(const char *s1, const char *s2, size_t n); 1038 1039 void strncasecmp_check_modelling() { 1040 char *x = "aa"; 1041 char *y = "a"; 1042 clang_analyzer_eval(strncasecmp(x, y, 2) > 0); // expected-warning{{TRUE}} 1043 clang_analyzer_eval(strncasecmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 1044 clang_analyzer_eval(strncasecmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 1045 1046 clang_analyzer_eval(strncasecmp(y, x, 2) < 0); // expected-warning{{TRUE}} 1047 clang_analyzer_eval(strncasecmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 1048 clang_analyzer_eval(strncasecmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 1049 } 1050 1051 void strncasecmp_constant0() { 1052 clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}} 1053 } 1054 1055 void strncasecmp_constant_and_var_0() { 1056 char *x = "abc"; 1057 clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}} 1058 } 1059 1060 void strncasecmp_constant_and_var_1() { 1061 char *x = "abc"; 1062 clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}} 1063 } 1064 1065 void strncasecmp_0() { 1066 char *x = "abc"; 1067 char *y = "Abc"; 1068 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1069 } 1070 1071 void strncasecmp_1() { 1072 char *x = "Bcd"; 1073 char *y = "abc"; 1074 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1075 } 1076 1077 void strncasecmp_2() { 1078 char *x = "abc"; 1079 char *y = "Bcd"; 1080 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1081 } 1082 1083 void strncasecmp_null_0() { 1084 char *x = NULL; 1085 char *y = "123"; 1086 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 1087 } 1088 1089 void strncasecmp_null_1() { 1090 char *x = "123"; 1091 char *y = NULL; 1092 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 1093 } 1094 1095 void strncasecmp_diff_length_0() { 1096 char *x = "abcde"; 1097 char *y = "aBd"; 1098 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1099 } 1100 1101 void strncasecmp_diff_length_1() { 1102 char *x = "abc"; 1103 char *y = "aBdef"; 1104 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1105 } 1106 1107 void strncasecmp_diff_length_2() { 1108 char *x = "aBcDe"; 1109 char *y = "abc"; 1110 clang_analyzer_eval(strncasecmp(x, y, 5) > 0); // expected-warning{{TRUE}} 1111 } 1112 1113 void strncasecmp_diff_length_3() { 1114 char *x = "aBc"; 1115 char *y = "abcde"; 1116 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1117 } 1118 1119 void strncasecmp_diff_length_4() { 1120 char *x = "abcde"; 1121 char *y = "aBc"; 1122 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1123 } 1124 1125 void strncasecmp_diff_length_5() { 1126 char *x = "abcde"; 1127 char *y = "aBd"; 1128 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1129 } 1130 1131 void strncasecmp_diff_length_6() { 1132 char *x = "aBDe"; 1133 char *y = "abc"; 1134 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1135 } 1136 1137 void strncasecmp_embedded_null () { 1138 clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 1139 } 1140 1141 //===----------------------------------------------------------------------=== 1142 // strsep() 1143 //===----------------------------------------------------------------------=== 1144 1145 char *strsep(char **stringp, const char *delim); 1146 1147 void strsep_null_delim(char *s) { 1148 strsep(&s, NULL); // expected-warning{{Null pointer argument in call to strsep()}} 1149 } 1150 1151 void strsep_null_search() { 1152 strsep(NULL, ""); // expected-warning{{Null pointer argument in call to strsep()}} 1153 } 1154 1155 void strsep_return_original_pointer(char *s) { 1156 char *original = s; 1157 char *result = strsep(&s, ""); // no-warning 1158 clang_analyzer_eval(original == result); // expected-warning{{TRUE}} 1159 } 1160 1161 void strsep_null_string() { 1162 char *s = NULL; 1163 char *result = strsep(&s, ""); // no-warning 1164 clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}} 1165 } 1166 1167 void strsep_changes_input_pointer(char *s) { 1168 char *original = s; 1169 strsep(&s, ""); // no-warning 1170 clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}} 1171 clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}} 1172 1173 // Check that the value is symbolic. 1174 if (s == NULL) { 1175 clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}} 1176 } 1177 } 1178 1179 void strsep_changes_input_string() { 1180 char str[] = "abc"; 1181 1182 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}} 1183 1184 char *s = str; 1185 strsep(&s, "b"); // no-warning 1186 1187 // The real strsep will change the first delimiter it finds into a NUL 1188 // character. For now, we just model the invalidation. 1189 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}} 1190 } 1191 1192 //===----------------------------------------------------------------------=== 1193 // memset() / explicit_bzero() / bzero() 1194 //===----------------------------------------------------------------------=== 1195 1196 void *memset(void *dest, int ch, size_t count); 1197 1198 void bzero(void *dst, size_t count); 1199 void explicit_bzero(void *dest, size_t count); 1200 1201 void *malloc(size_t size); 1202 void free(void *); 1203 1204 void memset1_char_array_null() { 1205 char str[] = "abcd"; 1206 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1207 memset(str, '\0', 2); 1208 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1209 } 1210 1211 void memset2_char_array_null() { 1212 char str[] = "abcd"; 1213 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1214 memset(str, '\0', strlen(str) + 1); 1215 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1216 clang_analyzer_eval(str[2] == 0); // expected-warning{{TRUE}} 1217 } 1218 1219 void memset3_char_malloc_null() { 1220 char *str = (char *)malloc(10 * sizeof(char)); 1221 memset(str + 1, '\0', 8); 1222 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1223 free(str); 1224 } 1225 1226 void memset4_char_malloc_null() { 1227 char *str = (char *)malloc(10 * sizeof(char)); 1228 //void *str = malloc(10 * sizeof(char)); 1229 memset(str, '\0', 10); 1230 clang_analyzer_eval(str[1] == 0); // expected-warning{{TRUE}} 1231 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1232 free(str); 1233 } 1234 1235 #ifdef SUPPRESS_OUT_OF_BOUND 1236 void memset5_char_malloc_overflow_null() { 1237 char *str = (char *)malloc(10 * sizeof(char)); 1238 memset(str, '\0', 12); 1239 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1240 free(str); 1241 } 1242 #endif 1243 1244 void memset6_char_array_nonnull() { 1245 char str[] = "abcd"; 1246 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1247 memset(str, '0', 2); 1248 clang_analyzer_eval(str[0] == 'a'); // expected-warning{{UNKNOWN}} 1249 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{UNKNOWN}} 1250 } 1251 1252 #ifdef SUPPRESS_OUT_OF_BOUND 1253 void memset8_char_array_nonnull() { 1254 char str[5] = "abcd"; 1255 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1256 memset(str, '0', 10); // expected-warning{{'memset' will always overflow; destination buffer has size 5, but size argument is 10}} 1257 clang_analyzer_eval(str[0] != '0'); // expected-warning{{UNKNOWN}} 1258 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1259 clang_analyzer_eval(strlen(str) < 10); // expected-warning{{FALSE}} 1260 } 1261 #endif 1262 1263 struct POD_memset { 1264 int num; 1265 char c; 1266 }; 1267 1268 void memset10_struct() { 1269 struct POD_memset pod; 1270 char *str = (char *)&pod; 1271 pod.num = 1; 1272 pod.c = 1; 1273 clang_analyzer_eval(pod.num == 0); // expected-warning{{FALSE}} 1274 memset(str, 0, sizeof(struct POD_memset)); 1275 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1276 } 1277 1278 #ifdef SUPPRESS_OUT_OF_BOUND 1279 void memset11_struct_field() { 1280 struct POD_memset pod; 1281 pod.num = 1; 1282 pod.c = '1'; 1283 memset(&pod.num, 0, sizeof(struct POD_memset)); 1284 1285 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1286 clang_analyzer_eval(pod.c == '\0'); // expected-warning{{TRUE}} 1287 } 1288 1289 void memset12_struct_field() { 1290 struct POD_memset pod; 1291 pod.num = 1; 1292 pod.c = '1'; 1293 memset(&pod.c, 0, sizeof(struct POD_memset)); // expected-warning {{'memset' will always overflow; destination buffer has size 4, but size argument is 8}} 1294 clang_analyzer_eval(pod.num == 0); // expected-warning{{UNKNOWN}} 1295 clang_analyzer_eval(pod.c == 0); // expected-warning{{UNKNOWN}} 1296 } 1297 1298 union U_memset { 1299 int i; 1300 double d; 1301 char c; 1302 }; 1303 1304 void memset13_union_field() { 1305 union U_memset u; 1306 u.i = 5; 1307 memset(&u.i, '\0', sizeof(union U_memset)); 1308 // Note: This should be TRUE, analyzer can't handle union perfectly now. 1309 clang_analyzer_eval(u.d == 0); // expected-warning{{UNKNOWN}} 1310 } 1311 #endif 1312 1313 void memset14_region_cast() { 1314 char *str = (char *)malloc(10 * sizeof(int)); 1315 int *array = (int *)str; 1316 memset(array, 0, 10 * sizeof(int)); 1317 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{TRUE}} 1318 clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}} 1319 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1320 free(str); 1321 } 1322 1323 void memset15_region_cast() { 1324 char *str = (char *)malloc(10 * sizeof(int)); 1325 int *array = (int *)str; 1326 memset(array, 0, 5 * sizeof(int)); 1327 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{UNKNOWN}} 1328 clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}} 1329 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1330 free(str); 1331 } 1332 1333 int memset20_scalar() { 1334 int *x = malloc(sizeof(int)); 1335 *x = 10; 1336 memset(x, 0, sizeof(int)); 1337 int num = 1 / *x; // expected-warning{{Division by zero}} 1338 free(x); 1339 return num; 1340 } 1341 1342 int memset21_scalar() { 1343 int *x = malloc(sizeof(int)); 1344 memset(x, 0, 1); 1345 int num = 1 / *x; 1346 free(x); 1347 return num; 1348 } 1349 1350 void memset22_array() { 1351 int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 1352 clang_analyzer_eval(array[1] == 2); // expected-warning{{TRUE}} 1353 memset(array, 0, sizeof(array)); 1354 clang_analyzer_eval(array[1] == 0); // expected-warning{{TRUE}} 1355 } 1356 1357 void memset23_array_pod_object() { 1358 struct POD_memset array[10]; 1359 array[1].num = 10; 1360 array[1].c = 'c'; 1361 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1362 memset(&array[1], 0, sizeof(struct POD_memset)); 1363 clang_analyzer_eval(array[1].num == 0); // expected-warning{{UNKNOWN}} 1364 } 1365 1366 void memset24_array_pod_object() { 1367 struct POD_memset array[10]; 1368 array[1].num = 10; 1369 array[1].c = 'c'; 1370 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1371 memset(array, 0, sizeof(array)); 1372 clang_analyzer_eval(array[1].num == 0); // expected-warning{{TRUE}} 1373 } 1374 1375 void memset25_symbol(char c) { 1376 char array[10] = {1}; 1377 if (c != 0) 1378 return; 1379 1380 memset(array, c, 10); 1381 1382 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1383 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1384 } 1385 1386 void memset26_upper_UCHAR_MAX() { 1387 char array[10] = {1}; 1388 1389 memset(array, 1024, 10); 1390 1391 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1392 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1393 } 1394 1395 void bzero1_null() { 1396 char *a = NULL; 1397 1398 bzero(a, 10); // expected-warning{{Null pointer argument in call to memory clearance function}} 1399 } 1400 1401 void bzero2_char_array_null() { 1402 char str[] = "abcd"; 1403 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1404 bzero(str, 2); 1405 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1406 } 1407 1408 void bzero3_char_ptr_null() { 1409 char *str = "abcd"; 1410 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1411 bzero(str + 2, 2); 1412 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{FALSE}} 1413 } 1414 1415 void explicit_bzero1_null() { 1416 char *a = NULL; 1417 1418 explicit_bzero(a, 10); // expected-warning{{Null pointer argument in call to memory clearance function}} 1419 } 1420 1421 void explicit_bzero2_clear_mypassword() { 1422 char passwd[7] = "passwd"; 1423 1424 explicit_bzero(passwd, sizeof(passwd)); // no-warning 1425 1426 clang_analyzer_eval(strlen(passwd) == 0); // expected-warning{{TRUE}} 1427 clang_analyzer_eval(passwd[0] == '\0'); // expected-warning{{TRUE}} 1428 } 1429 1430 void explicit_bzero3_out_ofbound() { 1431 char *privkey = (char *)malloc(7); 1432 const char newprivkey[10] = "mysafekey"; 1433 1434 strcpy(privkey, "random"); 1435 explicit_bzero(privkey, sizeof(newprivkey)); 1436 #ifndef SUPPRESS_OUT_OF_BOUND 1437 // expected-warning@-2 {{Memory clearance function accesses out-of-bound array element}} 1438 #endif 1439 clang_analyzer_eval(privkey[0] == '\0'); 1440 #ifdef SUPPRESS_OUT_OF_BOUND 1441 // expected-warning@-2 {{UNKNOWN}} 1442 #endif 1443 free(privkey); 1444 } 1445 1446 //===----------------------------------------------------------------------=== 1447 // FIXMEs 1448 //===----------------------------------------------------------------------=== 1449 1450 // The analyzer_eval call below should evaluate to true. We are being too 1451 // aggressive in marking the (length of) src symbol dead. The length of dst 1452 // depends on src. This could be explicitly specified in the checker or the 1453 // logic for handling MetadataSymbol in SymbolManager needs to change. 1454 void strcat_symbolic_src_length(char *src) { 1455 char dst[8] = "1234"; 1456 strcat(dst, src); 1457 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}} 1458 } 1459 1460 1461 // The analyzer_eval call below should evaluate to true. Most likely the same 1462 // issue as the test above. 1463 void strncpy_exactly_matching_buffer2(char *y) { 1464 if (strlen(y) >= 4) 1465 return; 1466 1467 char x[4]; 1468 strncpy(x, y, 4); // no-warning 1469 1470 // This time, we know that y fits in x anyway. 1471 clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}} 1472 } 1473 1474 void memset7_char_array_nonnull() { 1475 char str[5] = "abcd"; 1476 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1477 memset(str, '0', 5); 1478 // FIXME: This should be TRUE. 1479 clang_analyzer_eval(str[0] == '0'); // expected-warning{{UNKNOWN}} 1480 clang_analyzer_eval(strlen(str) >= 5); // expected-warning{{TRUE}} 1481 } 1482 1483 void memset16_region_cast() { 1484 char *str = (char *)malloc(10 * sizeof(int)); 1485 int *array = (int *)str; 1486 memset(array, '0', 10 * sizeof(int)); 1487 // FIXME: This should be TRUE. 1488 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1489 clang_analyzer_eval(strlen((char *)array) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1490 clang_analyzer_eval(strlen(str) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1491 free(str); 1492 } 1493 1494 #ifdef SUPPRESS_OUT_OF_BOUND 1495 void memset17_region_cast() { 1496 char *str = (char *)malloc(10 * sizeof(int)); 1497 int *array = (int *)str; 1498 memset(array, '0', 12 * sizeof(int)); 1499 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1500 clang_analyzer_eval(strlen((char *)array) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1501 clang_analyzer_eval(strlen(str) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1502 free(str); 1503 } 1504 1505 void memset18_memset_multiple_times() { 1506 char *str = (char *)malloc(10 * sizeof(char)); 1507 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1508 1509 memset(str + 2, '\0', 10 * sizeof(char)); 1510 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1511 clang_analyzer_eval(str[1] == '\0'); // expected-warning{{UNKNOWN}} 1512 1513 memset(str, '0', 10 * sizeof(char)); 1514 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1515 // FIXME: This should be TRUE. 1516 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1517 1518 free(str); 1519 } 1520 1521 void memset19_memset_multiple_times() { 1522 char *str = (char *)malloc(10 * sizeof(char)); 1523 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1524 1525 memset(str, '0', 10 * sizeof(char)); 1526 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1527 // FIXME: This should be TRUE. 1528 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1529 1530 memset(str + 2, '\0', 10 * sizeof(char)); 1531 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{UNKNOWN}} 1532 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1533 1534 free(str); 1535 } 1536 #endif 1537 1538 // The analyzer does not support binding a symbol with default binding. 1539 void memset27_symbol(char c) { 1540 char array[10] = {0}; 1541 if (c < 10) 1542 return; 1543 1544 memset(array, c, 10); 1545 1546 clang_analyzer_eval(strlen(array) >= 10); // expected-warning{{TRUE}} 1547 // FIXME: This should be TRUE. 1548 clang_analyzer_eval(array[4] >= 10); // expected-warning{{UNKNOWN}} 1549 } 1550 1551 void memset28() { 1552 short x; 1553 memset(&x, 1, sizeof(short)); 1554 // This should be true. 1555 clang_analyzer_eval(x == 0x101); // expected-warning{{UNKNOWN}} 1556 } 1557 1558 void memset29_plain_int_zero() { 1559 short x; 1560 memset(&x, 0, sizeof(short)); 1561 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} 1562 } 1563