189a1d03eSRichard // RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
289a1d03eSRichard // RUN: -config="{CheckOptions: \
3*e8a3ddafSNathan James // RUN: {bugprone-not-null-terminated-result.WantToUseSafeFunction: true}}" \
489a1d03eSRichard // RUN: -- -std=c11 -I %S/Inputs/not-null-terminated-result
589a1d03eSRichard 
689a1d03eSRichard #include "not-null-terminated-result-c.h"
789a1d03eSRichard 
889a1d03eSRichard // The following is not defined therefore the safe functions are unavailable.
989a1d03eSRichard // #define __STDC_LIB_EXT1__ 1
1089a1d03eSRichard 
1189a1d03eSRichard #define __STDC_WANT_LIB_EXT1__ 1
1289a1d03eSRichard 
1389a1d03eSRichard //===----------------------------------------------------------------------===//
1489a1d03eSRichard // memcpy() - destination array tests
1589a1d03eSRichard //===----------------------------------------------------------------------===//
1689a1d03eSRichard 
bad_memcpy_not_just_char_dest(const char * src)1789a1d03eSRichard void bad_memcpy_not_just_char_dest(const char *src) {
1889a1d03eSRichard   unsigned char dest00[13];
1989a1d03eSRichard   memcpy(dest00, src, strlen(src));
2089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
2189a1d03eSRichard   // CHECK-FIXES: unsigned char dest00[14];
2289a1d03eSRichard   // CHECK-FIXES-NEXT: strcpy((char *)dest00, src);
2389a1d03eSRichard }
2489a1d03eSRichard 
good_memcpy_not_just_char_dest(const char * src)2589a1d03eSRichard void good_memcpy_not_just_char_dest(const char *src) {
2689a1d03eSRichard   unsigned char dst00[14];
2789a1d03eSRichard   strcpy((char *)dst00, src);
2889a1d03eSRichard }
2989a1d03eSRichard 
bad_memcpy_known_dest(const char * src)3089a1d03eSRichard void bad_memcpy_known_dest(const char *src) {
3189a1d03eSRichard   char dest01[13];
3289a1d03eSRichard   memcpy(dest01, src, strlen(src));
3389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
3489a1d03eSRichard   // CHECK-FIXES: strcpy(dest01, src);
3589a1d03eSRichard }
3689a1d03eSRichard 
good_memcpy_known_dest(const char * src)3789a1d03eSRichard void good_memcpy_known_dest(const char *src) {
3889a1d03eSRichard   char dst01[13];
3989a1d03eSRichard   strcpy(dst01, src);
4089a1d03eSRichard }
4189a1d03eSRichard 
4289a1d03eSRichard //===----------------------------------------------------------------------===//
4389a1d03eSRichard // memcpy() - length tests
4489a1d03eSRichard //===----------------------------------------------------------------------===//
4589a1d03eSRichard 
bad_memcpy_full_source_length(const char * src)4689a1d03eSRichard void bad_memcpy_full_source_length(const char *src) {
4789a1d03eSRichard   char dest20[13];
4889a1d03eSRichard   memcpy(dest20, src, strlen(src));
4989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
5089a1d03eSRichard   // CHECK-FIXES: strcpy(dest20, src);
5189a1d03eSRichard }
5289a1d03eSRichard 
good_memcpy_full_source_length(const char * src)5389a1d03eSRichard void good_memcpy_full_source_length(const char *src) {
5489a1d03eSRichard   char dst20[13];
5589a1d03eSRichard   strcpy(dst20, src);
5689a1d03eSRichard }
5789a1d03eSRichard 
bad_memcpy_partial_source_length(const char * src)5889a1d03eSRichard void bad_memcpy_partial_source_length(const char *src) {
5989a1d03eSRichard   char dest21[13];
6089a1d03eSRichard   memcpy(dest21, src, strlen(src) - 1);
6189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
6289a1d03eSRichard   // CHECK-FIXES: strncpy(dest21, src, strlen(src) - 1);
6389a1d03eSRichard   // CHECK-FIXES-NEXT: dest21[strlen(src) - 1] = '\0';
6489a1d03eSRichard }
6589a1d03eSRichard 
good_memcpy_partial_source_length(const char * src)6689a1d03eSRichard void good_memcpy_partial_source_length(const char *src) {
6789a1d03eSRichard   char dst21[13];
6889a1d03eSRichard   strncpy(dst21, src, strlen(src) - 1);
6989a1d03eSRichard   dst21[strlen(src) - 1] = '\0';
7089a1d03eSRichard }
71