最近有一个关于SO(Why on earth would anyone use strncpy instead of strcpy?)的问题,其中有人回答(answer 1,answer 2),这使我不确定其他字符串函数名称中带有'n' ,就像snprintf
(我一直在广泛使用)。 snprintf可以安全使用吗?一般来说,'n'家族的安全功能是什么?
答案 0 :(得分:13)
strncpy()
是一个奇怪的函数,实际上是错误名称 - 它的最初目的是确保缓冲区已完全初始化为字符串的内容(不会溢出目标)和缓冲区的提示符为零。据我了解,最初的目的是处理文件系统目录条目 - 目标缓冲区实际上并不是与C库中其他strxxx()
函数相同的字符串。 strncpy()
的主要问题是,如果源字符串大于目标缓冲区,则结果将不会以空值终止。
处理字符串的大多数其他'n'函数都会正确终止字符串,但是有一些例外情况,例如Microsoft的bastardized _snprintf()
。正确的C99 snprintf()
将始终为null终止目标字符串(只要目标缓冲区的大小大于0)。
有一个'技术报告',TR 24731为处理字符串和内存缓冲区的函数提出了一组边界检查备选方案。 TR的目标之一是使函数的参数,结果和错误行为在各个函数中更相似。 TR似乎有点混合接受,我不认为除了微软的编译器之外它被广泛实现(我认为MS是TR背后的主要驱动因素)。你可以在这里获得更多信息:
即使你不是这些提案的粉丝,我认为他们也会就现有职能的问题进行教育性阅读。
答案 1 :(得分:1)
如果您为缓冲区提供正确的参数,snprintf
不会溢出缓冲区,请记住它与*printf
系列的其他成员共享所有格式字符串漏洞。例如,%n
说明符很讨厌,因为攻击者可以使用它来将任意字节写入任意内存位置。请参阅CERT C编码标准维基中的FIO30-C. Exclude user input from format strings。
答案 2 :(得分:0)
只要您为缓冲区提供正确的长度,它就是安全的。
答案 3 :(得分:-1)
snprintf确保不会覆盖缓冲区,但不保证空终止。如果您愿意不标准,可以在MSVC上使用sprintf_s
。
请参阅http://msdn.microsoft.com/en-us/library/2ts7cx93(VS.71).aspx
答案 4 :(得分:-2)
注意:不同的平台在传递给snprintf
的字符串的空终止方面有不同的行为。