2010-06-21 126 views
11

我试图搜索网站的这个问题,但没有发现这完全是,虽然这个问题被讨论了很多...什么时候全局静态常量变量被初始化?

我有这样的声明,以CPP文件,不在任何功能:

static const char* gText = "xxxxxxxxxxx"; 

虽然它有一个固定的大小,我从一个静态分析工具(Klocwork的)警告,当我试图把它复制到另一个字符*变量 - 对可能出界违例的:

char xText[32]; 
SecureZeroMemory(xText, 32); 
memcpy(xText, gText, strlen(gText)); 

这是假的吗? ive或是以后初始化的全局变量?

谢谢!

+0

KLOCWORKS所指的是哪一条? – ckv 2010-06-21 08:12:52

+0

memcpy()之一。 – IUnknownPointer 2010-06-21 09:26:47

+3

btw,指针本身不是const的,所以,它可以改为指向另一个更长的字符串 – sellibitze 2010-06-21 09:39:04

回答

1

这是一个误报。 strlen可能被抽象为返回一个未知的正数,所以当分析memcpy(dest,src,strlen(src));模式时,分析仪没有意识到只要src是格式良好的字符串,分析仪的读取部分就是安全的。

如果您使用的是strcpy,分析仪可能会得出结论,在这种情况下它可以。你有没有理由不?功能strcpy被视为“不安全”,但您的memcpy(..,src,strlen(src))也非常不安全。

编辑:另外,sellibitze提高在评论一个很好的点:原代码的const属性仅适用于由gText指向的字符,而不是gText本身。

+0

谢谢。 strcpy没有解决这个问题,但是我只在长度不超过边界的情况下才会限制复制。谢谢! – IUnknownPointer 2010-06-21 09:35:58

1

我会认为这不是假阳性。有可能会有人冒险来改变gText的长度而不知道它不能超过32个字符。我肯定会在memcpy之前进行某种检查,以确保不会有缓冲区溢出。

例如

char xText[32]; 
SecureZeroMemory(xText, 32); 
size_t lenToCopy = MIN(strlen(gText), 32); 
memcpy(xText, gText, lenToCopy); 

另外,我会用一个常量替换魔术数32。

+0

我对一个非常相似的评论发表了评论,并且其作者已将其删除。所以我不会再重复同样的事情,但既然你已经决定使用'gText'的所有可能的值,为什么假设'gText'是一个格式良好的字符串(在char上调用'strlen'是非法的数组不是一个格式良好的字符串)? – 2010-06-21 09:15:53

+1

如果'xText'在复制后应该包含格式正确的字符串,那么'MIN(..,32)'中的'32'应该是'31'。 – 2010-06-21 09:19:23

+0

@Pascal:使用memcpy而不是字符串函数意味着我的意图是获得将被视为固定大小的字节块而不是C字符串的东西。这就是为什么我将限制设置为32.如果我试图复制一个字符串,我会使用strncpy(或等价的)来完成它 - 或者这是C++ std :: string。 – JeremyP 2010-06-21 09:29:35