| 1 | // RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \ |
| 2 | // RUN: -config="{CheckOptions: \ |
| 3 | // RUN: {bugprone-not-null-terminated-result.WantToUseSafeFunction: true}}" \ |
| 4 | // RUN: -- -std=c11 -I %S/Inputs/not-null-terminated-result |
| 5 | |
| 6 | #include "not-null-terminated-result-c.h" |
| 7 | |
| 8 | // The following is not defined therefore the safe functions are unavailable. |
| 9 | // #define __STDC_LIB_EXT1__ 1 |
| 10 | |
| 11 | #define __STDC_WANT_LIB_EXT1__ 1 |
| 12 | |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | // memcpy() - destination array tests |
| 15 | //===----------------------------------------------------------------------===// |
| 16 | |
| 17 | void bad_memcpy_not_just_char_dest(const char *src) { |
| 18 | unsigned char dest00[13]; |
| 19 | memcpy(dest00, src, strlen(src)); |
| 20 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result] |
| 21 | // CHECK-FIXES: unsigned char dest00[14]; |
| 22 | // CHECK-FIXES-NEXT: strcpy((char *)dest00, src); |
| 23 | } |
| 24 | |
| 25 | void good_memcpy_not_just_char_dest(const char *src) { |
| 26 | unsigned char dst00[14]; |
| 27 | strcpy((char *)dst00, src); |
| 28 | } |
| 29 | |
| 30 | void bad_memcpy_known_dest(const char *src) { |
| 31 | char dest01[13]; |
| 32 | memcpy(dest01, src, strlen(src)); |
| 33 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result] |
| 34 | // CHECK-FIXES: strcpy(dest01, src); |
| 35 | } |
| 36 | |
| 37 | void good_memcpy_known_dest(const char *src) { |
| 38 | char dst01[13]; |
| 39 | strcpy(dst01, src); |
| 40 | } |
| 41 | |
| 42 | //===----------------------------------------------------------------------===// |
| 43 | // memcpy() - length tests |
| 44 | //===----------------------------------------------------------------------===// |
| 45 | |
| 46 | void bad_memcpy_full_source_length(const char *src) { |
| 47 | char dest20[13]; |
| 48 | memcpy(dest20, src, strlen(src)); |
| 49 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result] |
| 50 | // CHECK-FIXES: strcpy(dest20, src); |
| 51 | } |
| 52 | |
| 53 | void good_memcpy_full_source_length(const char *src) { |
| 54 | char dst20[13]; |
| 55 | strcpy(dst20, src); |
| 56 | } |
| 57 | |
| 58 | void bad_memcpy_partial_source_length(const char *src) { |
| 59 | char dest21[13]; |
| 60 | memcpy(dest21, src, strlen(src) - 1); |
| 61 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result] |
| 62 | // CHECK-FIXES: strncpy(dest21, src, strlen(src) - 1); |
| 63 | // CHECK-FIXES-NEXT: dest21[strlen(src) - 1] = '\0'; |
| 64 | } |
| 65 | |
| 66 | void good_memcpy_partial_source_length(const char *src) { |
| 67 | char dst21[13]; |
| 68 | strncpy(dst21, src, strlen(src) - 1); |
| 69 | dst21[strlen(src) - 1] = '\0'; |
| 70 | } |
| 71 | |