1// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
2// RUN: -- -std=c++11 -I %S/Inputs/not-null-terminated-result
3
4#include "not-null-terminated-result-cxx.h"
5
6#define __STDC_LIB_EXT1__ 1
7#define __STDC_WANT_LIB_EXT1__ 1
8
9//===----------------------------------------------------------------------===//
10// memcpy() - destination array tests
11//===----------------------------------------------------------------------===//
12
13void bad_memcpy_not_just_char_dest(const char *src) {
14 unsigned char dest00[13];
15 memcpy(dest00, src, strlen(src));
16 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
17 // CHECK-FIXES: unsigned char dest00[14];
18 // CHECK-FIXES-NEXT: strcpy_s((char *)dest00, 14, src);
19}
20
21void good_memcpy_not_just_char_dest(const char *src) {
22 unsigned char dst00[14];
23 strcpy_s((char *)dst00, 14, src);
24}
25
26void bad_memcpy_known_dest(const char *src) {
27 char dest01[13];
28 memcpy(dest01, src, strlen(src));
29 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
30 // CHECK-FIXES: dest01[14];
31 // CHECK-FIXES-NEXT: strcpy_s(dest01, src);
32}
33
34void good_memcpy_known_dest(const char *src) {
35 char dst01[14];
36 strcpy_s(dst01, src);
37}
38
39//===----------------------------------------------------------------------===//
40// memcpy() - length tests
41//===----------------------------------------------------------------------===//
42
43void bad_memcpy_full_source_length(std::string src) {
44 char *dest20 = reinterpret_cast<char *>(malloc(src.size()));
45 memcpy(dest20, src.data(), src.size());
46 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
47 // CHECK-FIXES: dest20 = reinterpret_cast<char *>(malloc(src.size() + 1));
48 // CHECK-FIXES-NEXT: strcpy(dest20, src.data());
49}
50
51void good_memcpy_full_source_length(std::string src) {
52 char dst20[14];
53 strcpy_s(dst20, src.data());
54}
55
56void bad_memcpy_partial_source_length(const char *src) {
57 char dest21[13];
58 memcpy(dest21, src, strlen(src) - 1);
59 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
60 // CHECK-FIXES: char dest21[14];
61 // CHECK-FIXES-NEXT: strncpy_s(dest21, src, strlen(src) - 1);
62}
63
64void good_memcpy_partial_source_length(const char *src) {
65 char dst21[14];
66 strncpy_s(dst21, src, strlen(src) - 1);
67}
68
69//===----------------------------------------------------------------------===//
70// memcpy_s() - destination array tests
71//===----------------------------------------------------------------------===//
72
73void bad_memcpy_s_unknown_dest(char *dest40, const char *src) {
74 memcpy_s(dest40, 13, src, strlen(src));
75 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
76 // CHECK-FIXES: strcpy_s(dest40, 13, src);
77}
78
79void good_memcpy_s_unknown_dest(char *dst40, const char *src) {
80 strcpy_s(dst40, 13, src);
81}
82
83void bad_memcpy_s_known_dest(const char *src) {
84 char dest41[13];
85 memcpy_s(dest41, 13, src, strlen(src));
86 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
87 // CHECK-FIXES: char dest41[14];
88 // CHECK-FIXES: strcpy_s(dest41, src);
89}
90
91void good_memcpy_s_known_dest(const char *src) {
92 char dst41[14];
93 strcpy_s(dst41, src);
94}
95
96//===----------------------------------------------------------------------===//
97// memcpy_s() - length tests
98//===----------------------------------------------------------------------===//
99
100void bad_memcpy_s_full_source_length(const char *src) {
101 char dest60[13];
102 memcpy_s(dest60, 13, src, strlen(src));
103 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
104 // CHECK-FIXES: char dest60[14];
105 // CHECK-FIXES-NEXT: strcpy_s(dest60, src);
106}
107
108void good_memcpy_s_full_source_length(const char *src) {
109 char dst60[14];
110 strcpy_s(dst60, src);
111}
112
113void bad_memcpy_s_partial_source_length(const char *src) {
114 char dest61[13];
115 memcpy_s(dest61, 13, src, strlen(src) - 1);
116 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
117 // CHECK-FIXES: char dest61[14];
118 // CHECK-FIXES-NEXT: strncpy_s(dest61, src, strlen(src) - 1);
119}
120
121void good_memcpy_s_partial_source_length(const char *src) {
122 char dst61[14];
123 strncpy_s(dst61, src, strlen(src) - 1);
124}
125

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp