背景
考虑以下代码:
template <typename T>
void WriteData(const size_t &offset, const T &data)
{
if(sizeof(data) <= 8) //if size is 64bits or less, memcpy is not as efficient as a direct write
*reinterpret_cast<T*>(reinterpret_cast<char*>(_memView) + offset) = data;
else
{
errno_t result = memcpy_s(reinterpret_cast<char*>(_memView) + offset, SHARED_BUFFER_SIZE - offset, &data, sizeof(data));
if(result != 0)
throw exception("Error writing data");
}
}假设_memView被声明为一个空指针。memcpy_s在任何地方都没有重新定义。
函数只使用以下类型实例化: char、int、HANDLE、unsigned、long和unsigned。不要因为这个片段而陷入其他问题,这是关于klocwork的。
这个模板代码是类的一部分,因此它位于一个头文件中。
如果我漏掉了其他相关信息,就问问吧。
问题
在对Klocwork进行分析之后,我得到了SV.BANNED.COPY警告:“不要使用不安全的缓冲区复制函数--考虑使用strcpy_s之类的安全变体”
那么,我是不是在用我称之为memcpy_s的方式做一些脑死亡的事情,Klocwork是否认为memcpy_s是不安全的?Klocwork是否对char*的转换感到困惑,并认为我正在操作C样式的字符串?
我想了解Klocwork想告诉我的是什么,即使它只是告诉我这是个假阳性。
发布于 2014-08-21 13:57:00
根据标准的C++,这个功能是各种各样的坏的。
if分支执行未对齐的写入,并违反严格的混叠。这两个分支都会很高兴地注销缓冲区的末尾。
if分支根本不检查大小。else分支受无符号进位的限制。memcpy_s不是万灵药.使用memcpy并将一些思想应用于参数验证将避免每次对memcpy_s的盲目调用。
更正版本:
template <typename T>
void WriteData(const size_t &offset, const T &data)
{
if (sizeof data > SHARED_BUFFER_SIZE)
throw exception("Type cannot fit in shared buffer");
if (offset > SHARED_BUFFER_SIZE - sizeof data)
throw exception("Copy would overrun end of shared buffer");
memcpy(reinterpret_cast<char*>(_memView) + offset, &data, sizeof data);
}要有效地处理小副本,请确保您的编译器将memcpy作为一个内部处理是启用的。
https://stackoverflow.com/questions/25428082
复制相似问题