C6053
警告 C6053:对 <function> 的调用不能为字符串 <variable> 添加字符串零终止符
此警告指出已使用可能导致得到的字符串不以零结尾的方式调用指定的函数。 此缺陷可能会导致可利用的缓冲区溢出或系统故障。 如果带批注的函数接受以 Null 终止的字符串(在它的 Pre 条件中使用 NullTerminated 属性),则当向该函数传递不以 Null 终止的字符串时,也会生成此警告。
大多数 C 标准库和 Win32 字符串处理函数都需要并生成以零结尾的字符串。 对于少数“计数字符串”函数(包括 strncpy、wcsncpy、_mbsncpy、_snprintf 和 snwprintf)来说,如果它们完全填充其缓冲区,则不会生成以零结尾的字符串。 在这种情况下,在以后调用接受以零结尾的字符串的字符串函数时,将在超出缓冲区末尾的范围查找零。 程序应当确保字符串以零结尾。 通常,一种有用的方法是,向“计数字符串”函数传递比缓冲区大小小一的长度,然后将零显式赋给缓冲区中的最后一个字符。
示例
下面的代码示例生成此警告:
#include <string.h>
#define MAX 15
size_t f( )
{
char szDest[MAX];
char *szSource="Hello, World!";
strncpy(szDest, szSource, MAX);
return strlen(szDest); // possible crash here
}
若要更正此警告,请在字符串的末尾添加零终止符,如下面的代码示例所示:
#include <string.h>
#define MAX 15
size_t f( )
{
char szDest[MAX];
char *szSource="Hello, World!";
strncpy(szDest, szSource, MAX-1);
szDest[MAX-1]=0;
return strlen(szDest);
}
下面的代码示例使用安全的字符串操作函数 strncpy_s 来更正此警告:
#include <string.h>
#define MAX 15
size_t f( )
{
char szDest[MAX];
char *szSource= "Hello, World!";
strncpy_s(szDest, sizeof(szDest), szSource, strlen(szSource));
return strlen(szDest);
}
下面的代码使用批注来生成警告 C6053:
#include<codeanalysis\sourceannotations.h>
using namespace vc_attributes;
void NotNullTerminatedStringReturned
(
[Post(NullTerminated=No)] char* str
)
{
// code ...
}
void NullTerminatedStringRequired ([Pre(NullTerminated=Yes)] char* str)
{
// code ...
}
void f (char* pC )
{
NotNullTerminatedStringReturned(pC); //pC is not null terminated
NullTerminatedStringRequired(pC); //requires null terminated pC
}
应当注意的是,有时会用某些实际上能够确保安全的用语报告此警告。 因为此缺陷以一定的频率出现并且可能产生一些后果,所以分析工具偏重于查找可能的问题,而不是像通常那样偏重于减少问题。
请参见
参考
strncpy_s, _strncpy_s_l, wcsncpy_s, _wcsncpy_s_l, _mbsncpy_s, _mbsncpy_s_l