0

strncpy()iPhone 开发安全吗?

如果没有,建议使用什么更好的 String API 以确保安全?

4

2 回答 2

5

如果你知道 的局限性strncpy(),那就没问题了。我避免使用它是因为我不喜欢它的局限性,这有两个方面:

  • 它不保证空终止
  • 它总是写入目标缓冲区的每个字节

这意味着如果你写:

char little[10];
char large[20480];

strncpy(little, sizeof(little), "abcdefghijklmnopqrstuvwxyz");
strncpy(large,  sizeof(large),  "abcdefghijklmnopqrstuvwxyz");

thenlittle不是一个以 null 结尾的字符串,尽管没有发生缓冲区溢出,并且 large 有 20454 个 null 复制到它的尾端。两者都很麻烦。

  • 考虑是否在 iOSstrlcpy()strlcat()可用;它们在 Mac OS X 上。

如果您使用 C++ 编码,则根本不应该使用 C 字符串,或者仅在系统服务需要使用的最有限的情况下使用,然后您应该有一个采用 C++ 字符串的覆盖函数(内联)并将somestring.c_str()值传递给系统服务。

如果您使用 Objective-C 进行编码,您将使用 NS* 字符串。

因此,仅考虑strncpy()您是否使用 C 进行编码。即便如此,也要谨慎对待。

我有一篇论文(我不声称它有任何新颖性——我从其他人那里收集了这个想法):

  • 如果您知道字符串的长度、目标缓冲区和源字符串的长度(并且您知道您正在调用的函数的缺点——很快,传递的长度代表什么) ,您只能安全地使用像strcpy()、和之类的函数? (1) )。strncpy()strcat()strncat()strncat()
  • 如果你知道每件事有多长,你就不需要使用像strcpy();这样的函数。您可以使用memmove()(或memcpy())。
  • 所以字符串复制和移动功能应该是无关紧要的;您不需要在安全代码中使用它们,因为您知道所有内容有多长,因此可以使用内存例程。

(1)长度是考虑到当前字符串后目标缓冲区中的可用空间。因此,为了能够使用strncat(),您必须知道字符串在目标字符串中的长度以及可用的总长度,以便您可以strncat()跳过字符串的初始段,然后连接第二个字符串的部分或全部. 但是,如果你知道这一点,你可以使用:

strncpy(target + curr_target_strlen, source, target_size - curr_target_strlen);

这将“更有效”,因为它不涉及跳过字符串的前导部分(顺便说一句,如果您正在构建一个包含大量strncat()orstrcat()操作的长字符串,这可能会导致二次行为)。或者,鉴于您知道所有尺寸,您可以使用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。

于 2012-04-18T03:26:41.733 回答
0

指定您对安全的含义,无论如何strncpy在 iPhone 上与在其他所有平台上一样安全。

既然你需要strncpy我猜你没有使用NSStrings 所以我认为使用它没有任何问题。

于 2012-04-18T03:17:00.613 回答