0

在通过一些 c++ 代码作为 PCI DSS 认证审查的一部分时,我遇到了以下问题:

我在我们使用的某个库中有一个方法,它的一个参数是 char *,可以说这是

void foo(char* arg);

代码中调用此方法的位置如下所示:

char mystring[256];
strcpy(mystring, "some value");
....
foo(mystring);

作为审查的一部分,我们正在摆脱任何 strcpy 调用(尽管在这个例子中它有点微不足道,因为“一些值”显然适合 mystring)

所以我们得到:

char mystring[256];
strncpy(mystring, "some value", sizeof(mystring));
mystring[sizeof(mystring)-1] = '\0';
....
foo(mystring);

这是因为我认为

foo("some value")

会通过一个const char *

然而令我惊讶的是,编译器(gcc 4)对此非常满意。当我添加 -Wall 或 -Wcast-qual 时,它甚至没有给出任何警告

我的问题是:在这种情况下,当我不知道 foo 对其参数实际上做了什么(如果有的话)时,我可以安全地调用 foo("some value") 吗?

4

3 回答 3

10

不,如果你不能保证 foo 不会修改参数,那是不安全的。编译器可以隐式转换字符串文字以char *向后兼容 C 代码(不幸的是)。您必须将文字复制到可修改的字符缓冲区并传递它。

于 2013-10-11T13:24:24.693 回答
8

foo("some value")在这种情况下,当我不知道foo它的论点实际上在做什么(如果有的话)时,我可以安全地打电话吗?

不。字符串文字是常量,尝试修改它会产生未定义的行为。

由于历史原因,一些编译器允许对非常量进行过时的转换char*——尽管这种转换自 C++11 起不再有效。你不应该依赖它,希望你可以提高编译器的警告级别来防止它。

然而令我惊讶的是,编译器(gcc 4)对此非常满意。

这是令人惊讶的。我的 GCC 4.6.3 默认给出警告;我需要指定-Wno-write-strings使其静音。

于 2013-10-11T13:24:51.410 回答
2

顺便说一句,你用strncpy错了。size 参数应该是目标缓冲区的大小减一:

char mystring[256];
strncpy(mystring, "some value", 255);
mystring[255] = '\0';

目标是防止缓冲区溢出。

于 2013-10-11T13:38:25.370 回答