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