strncpy()
iPhone 开发安全吗?
如果没有,建议使用哪个更好的字符串 API 来确保安全?
如果你知道strncpy()
的局限性,那就没问题了。 我避免它,因为我不喜欢它的局限性,这是双重的:
- 它不保证空终止
- 它始终写入目标缓冲区的每个字节
这意味着,如果您编写:
char little[10];
char large[20480];
strncpy(little, sizeof(little), "abcdefghijklmnopqrstuvwxyz");
strncpy(large, sizeof(large), "abcdefghijklmnopqrstuvwxyz");
然后little
不是以 null 结尾的字符串,尽管没有发生缓冲区溢出,并且 large 将 20454 个 null 复制到其尾端。 两者都很麻烦。
- 考虑
strlcpy()
和strlcat()
在iOS上是否可用;它们在Mac OS X上可用。
如果使用 C++ 进行编码,则根本不应使用 C 字符串,或者仅在系统服务需要使用的最有限情况下使用,然后应该有一个 cover 函数(内联),该函数采用C++字符串并将somestring.c_str()
值传递给系统服务。
如果你用Objective-C编码,你将使用NS*字符串。
因此,只有在使用 C 编码时才考虑strncpy()
。 即便如此,也要谨慎对待。
有一篇论文(我并不声称其中有任何新颖性——我从其他人那里收集了这个想法):
- 只有当你知道字符串的
- 长度,目标缓冲区和源字符串(并且你知道你正在调用的函数的弱点)时,你才能安全地使用
strcpy()
、strncpy()
、strcat()
和strncat()
这样的函数——很快,传递给strncat()
的长度代表什么?(1))。 - 如果你知道每件事有多长,你就不需要使用像
strcpy()
这样的函数;你可以使用memmove()
(或memcpy()
)。
因此, - 字符串复制和移动函数应该是无关紧要的;您不需要在安全代码中使用它们,因为您知道所有内容有多长,因此可以使用内存例程。
(1) 长度是考虑当前字符串后目标缓冲区中的可用空间。 因此,为了能够使用 strncat()
,您必须知道字符串在目标字符串中的长度以及可用的总长度,以便strncat()
您可以跳过字符串的初始段,然后连接部分或全部第二个字符串。 但是,如果您知道这一点,则可以使用:
strncpy(target + curr_target_strlen, source, target_size - curr_target_strlen);
这将"更有效",因为它不涉及跳过字符串的前导部分(顺便说一下,如果您正在构建具有大量strncat()
或strcat()
操作的长字符串,这可能会导致二次行为)。 或者,鉴于您知道所有尺寸,您可以使用memmove()
:
size_t copy_length = target_size - curr_target_strlen;
if (copy_length > source_strlen)
copy_length = source_strlen + 1;
memmove(target + curr_target_strlen, source, copy_length);
而且,除非我在一时冲动编写的代码中出现一个错误,否则可以避免strncat()
的大部分问题。 如果您总是使用strncat()
,第一个参数指向字符串末尾的 null,则它有其用途(并且可以在汇编程序中进行优化。 否则,这不是一个好的选择——IMNSHO。
指定您对安全的含义,在任何情况下,iPhone 上的strncpy
都与其他所有平台上一样安全。
由于您需要strncpy
我想您没有使用 NSString
s,所以我认为使用它没有任何问题。