strncpy()
对于iPhone开发是否安全?
如果不是,那么建议使用哪种更好的String API以确保安全?
最佳答案
如果您知道strncpy()
的限制,那么可以。我避免使用它是因为我不喜欢它的局限性,它有两个方面:
它不保证空终止
它总是写入目标缓冲区的每个字节
这意味着如果您编写:
char little[10];
char large[20480];
strncpy(little, sizeof(little), "abcdefghijklmnopqrstuvwxyz");
strncpy(large, sizeof(large), "abcdefghijklmnopqrstuvwxyz");
然后,尽管没有发生缓冲区溢出,但
little
并不是一个以空值结尾的字符串,并且大号将20454个空值复制到其尾端。两者都很麻烦。考虑
strlcpy()
和strlcat()
在iOS上是否可用;它们在Mac OS X上。如果您使用C ++进行编码,则根本不应该使用C字符串,或者仅在系统服务需要使用的最有限的情况下才使用C字符串,然后应该具有使用C ++字符串的Cover函数(内联)。并将
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对于iPhone开发是否安全?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10202266/