如何更安全地编写这个C 片段?
我有以下 C 代码片段,必须识别错误并建议一种更安全的编写方法:
char somestring[] = "Send money!\n";
char *copy;
copy = (char *) malloc(strlen(somestring));
strcpy(copy, somestring);
printf(copy);
所以错误是 strlen 忽略了字符串的尾部 '\0'
,因此它是不会为副本分配足够的内存,但我不确定他们如何更安全地编写副本?
我认为我可以使用 malloc(strlen(somestring)+1)) 但我想一定有比这更好的方法吗?
编辑:好的,我已经接受了答案,我怀疑我们不会期望 strdup 解决方案,因为它不是 ANSI C 的一部分。这似乎是一个相当主观的问题,所以我不确定我所接受的是否真的是最好的。 无论如何,感谢所有的答案。
I have the following C code fragment and have to identify the error and suggest a way of writing it more safely:
char somestring[] = "Send money!\n";
char *copy;
copy = (char *) malloc(strlen(somestring));
strcpy(copy, somestring);
printf(copy);
So the error is that strlen ignores the trailing '\0'
of a string and therefore it is not going to be allocated enough memory for the copy but I'm not sure what they're getting at about writing it more safely?
I could just use malloc(strlen(somestring)+1))
I assume but I'm thinking there must be a better way than that?
EDIT: OK, I've accepted an answer, I suspect that the strdup solution would not be expected from us as it's not part of ANSI C. It seems to be quite a subjective question so I'm not sure if what I've accepted is actually the best. Thanks anyway for all the answers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
使代码更安全(并且更正确)的方法。
somestring
。 直接输出即可。malloc
的返回值。malloc
的内存。printf
。 使用printf("%s", copy)
或puts(copy)
。Ways to make the code safer (and more correct).
somestring
. You can output it directly.malloc
.malloc
'ed memory.printf
with an untrusted format string. Useprintf("%s", copy)
orputs(copy)
.如果一个人真正对这样的事情感兴趣,那么更安全地编写它的最好方法就是用 Ada 编写它。
结果一样,那么有什么区别呢?
(没有指针)。 解除分配是
自动且安全。
不可能出现缓冲区溢出
两个字符串都是
所以没有机会搞砸
并修改它们。
请注意,在 Ada 中,“字符串”并不是某种特殊的动态构造。 它是内置的字符数组。 但是,Ada 数组可以在声明时根据您分配给它们的数组来调整大小。
The best way to write it more safely, if one were to be truly interested in such a thing, would be to write it in Ada.
Same result, so what are the differences?
(no pointers). Deallocation is
automatic and safe.
there's no chance of buffer-overflow
exploits
so there's no chance of screwing up
and modifying them.
Note that in Ada "string" is not some special dynamic construct. It's the built-in array of characters. However, Ada arrays can be sized at declaration by the array you assign into them.
更安全的方法是使用
strncpy
而不是strcpy
。 该函数采用第三个参数:要复制的字符串的长度。 该解决方案不会超出 ANSI C,因此这将在所有环境下工作(而其他方法可能仅在符合 POSIX 标准的系统下工作)。The safer way would be to use
strncpy
instead ofstrcpy
. That function takes a third argument: the length of the string to copy. This solution doesn't stretch beyond ANSI C, so this will work under all environments (whereas other methods may only work under POSIX-compliant systems).我无法对上面的回复发表评论,但除了检查
返回代码并使用
strncpy
,你永远不应该这样做:但使用:
ref: http ://en.wikipedia.org/wiki/Format_string_attack
I can't comment on the responses above, but in addition to checking the
return code and using
strncpy
, you should never do:But use:
ref: http://en.wikipedia.org/wiki/Format_string_attack
或者只是将此逻辑放入单独的函数xstrdup中:
or just put this logic in a separate function xstrdup:
注意上面的差异:
malloc()
的结果!strncpy()
因为strcpy()
很顽皮。 在这个人为的例子中,它不会造成伤害,但不要养成使用它的习惯。编辑:
对于那些认为我应该使用
strdup()
的人...只有当您对问题采取最狭隘的看法时才有效。 这不仅愚蠢,而且忽视了一个更好的答案:如果你要变得迟钝,至少要擅长它。
Noted differences above:
malloc()
must be checked!strncpy()
becausestrcpy()
is naughty. In this contrived example it won't hurt, but don't get into the habit of using it.EDIT:
To those thinking I should be using
strdup()
... that only works if you take the very narrowest view of the question. That's not only silly, it's overlooking an even better answer:If you're going to be obtuse, at least be good at it.
哎呀...像其他人所说的那样使用
strdup()
并在必要时自己编写。 既然您现在有时间考虑这个问题...请查看 25 Mitre 上最危险的编程错误,然后考虑为什么短语printf(copy)
不应该永远出现在代码中。 就彻底的糟糕性而言,这与 malloc(strlen(str)) 不相上下,更不用说当复制类似于"%s 时,追踪为什么它会引起很多悲伤的头痛。 %n"
...Ick... use
strdup()
like everyone else said and write it yourself if you have to. Since you have time to think about this now... check out the 25 Most Dangerous Programming Errors at Mitre, then consider why the phraseprintf(copy)
should never appear in code. That is right up there withmalloc(strlen(str))
in terms of utter badness not to mention the headache of tracking down why it causes lots of grief when copy is something like"%s%n"
...我会对以前的解决方案发表评论,但我没有足够的代表。
在这里使用 strncpy 与使用 strcpy 一样错误(因为绝对没有溢出风险)。 中有一个名为memcpy的函数 string.h > 正是为此而设计的。 它不仅速度明显更快,而且是用于复制标准 C 中已知长度字符串的正确函数。
从已接受的答案来看:
I would comment to previous solutions but I do not have enough rep.
Using strncpy here is as wrong as using strcpy(As there is absolutely no risk of overflow). There is a function called memcpy in < string.h > and it is meant exactly for this. It is not only significantly faster, but also the correct function to use to copy strings of known length in standard C.
From the accepted answer:
为了添加更多 Adrian McCarthy 的方法来制作更安全的代码,
请使用静态代码分析器,他们非常擅长发现此类错误
to add more to Adrian McCarthy's ways to make safer code,
Use a static code analyzer, they are very good at finding this kind of errors