怎样才能更安全地编写这个C片段?

Ada*_*lor 5 c memory-management cstring strdup null-terminated

我有以下C代码片段,必须识别错误并建议更安全地编写它的方法:

char somestring[] = "Send money!\n";
char *copy;

copy = (char *) malloc(strlen(somestring));

strcpy(copy, somestring);
printf(copy);
Run Code Online (Sandbox Code Playgroud)

所以错误是strlen忽略'\0'了字符串的尾随,因此不会为副本分配足够的内存,但是我不确定他们更安全地写它是什么?

我可以使用malloc(strlen(somestring)+1))我假设,但我认为必须有一个比这更好的方法?


编辑:好的,我接受了答案,我怀疑我们不会期待strdup解决方案,因为它不是ANSI C的一部分.这似乎是一个非常主观的问题,所以我不确定我是不是接受实际上是最好的.无论如何,谢谢你的所有答案.

小智 7

我无法评论上面的回复,但除了检查返回代码和使用之外strncpy,你永远不应该做:

printf(string)
Run Code Online (Sandbox Code Playgroud)

但使用:

printf("%s", string);
Run Code Online (Sandbox Code Playgroud)

参考:http://en.wikipedia.org/wiki/Format_string_attack

  • +1表示大多数常见代码中的意外安全漏洞 (2认同)

dfa*_*dfa 6

char somestring[] = "Send money!\n";
char *copy = strdup(something);

if (copy == NULL) {
    // error
}
Run Code Online (Sandbox Code Playgroud)

或者只是将这个逻辑放在一个单独的函数xstrdup中:

char * xstrdup(const char *src) 
{
    char *copy = strdup(src);

    if (copy == NULL) {
       abort();
    }

    return copy;
}
Run Code Online (Sandbox Code Playgroud)

  • 应该注意strdup()不是ANSI C的一部分. (5认同)
  • 如果您的C库不存在strdup(),那么您应该编写它.这意味着您只有一个点可以发生错误而不是数百个错误. (2认同)

dwc*_*dwc 4

char   somestring[] = "Send money!\n";
char   *copy;
size_t copysize;

copysize = strlen(somestring)+1;
copy = (char *) malloc(copysize);
if (copy == NULL)
    bail("Oh noes!\n");

strncpy(copy, somestring, copysize);
printf("%s", copy);
Run Code Online (Sandbox Code Playgroud)

上面注意到的差异:

  • malloc()必须检查结果!
  • 计算并存储内存大小!
  • 使用是strncpy()因为strcpy()很顽皮。在这个人为的例子中,它不会造成伤害,但不要养成使用它的习惯。

编辑:

对于那些认为我应该使用strdup()...的人来说,只有当您对问题采取最狭隘的看法时,这才有效。这不仅愚蠢,而且忽略了一个更好的答案:

char somestring[] = "Send money!\n";
char *copy = somestring;
printf(copy);
Run Code Online (Sandbox Code Playgroud)

如果你要变得迟钝,至少要擅长它。

  • 错误地使用 strncpy() 比错误地使用 strcpy() 更糟糕。如果您使用 strncpy(),则 *不* 保证以 null 结尾的输出(此示例可以,但一般情况下不行)。另外,如果您使用过大的缓冲区和 sizeof(buffer) 作为 strncpy() 的第三个参数,那么您将面临性能小灾难;strncpy() 热心地将复制的数据用零填充到完整长度。*是*知道源字符串和目标字符串的长度;如果你做得正确,使用 strcpy() 是安全的,并且比盲目使用 strncpy() 更安全。(如果有帮助的话,strncat() 比 strncpy() 差得多;永远不要使用它!) (8认同)
  • +1 用于 strncpy 的使用。这就是这么多安全漏洞的根源,这并不好笑。 (3认同)