对于iPhone开发来说,strncpy安全吗?

时间:2012-04-18 03:15:43

标签: iphone c++ string printf

对于iPhone开发,strncpy()是否安全?

如果没有,建议使用哪种更好的String API是安全的?

2 个答案:

答案 0 :(得分:5)

如果你知道strncpy()的限制,那就没关系。我避免它,因为我不喜欢它的局限性,这有两个方面:

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

这意味着如果你写:

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

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

然后little不是以空字符结尾的字符串,尽管没有发生缓冲区溢出,并且大的已将20454个空值复制到其尾端。两者都很麻烦。

  • 考虑iOS上是否有strlcpy()strlcat();它们在Mac OS X上。

如果您使用C ++进行编码,则根本不应该使用C字符串,或者仅在系统服务需要使用的最有限的情况下使用,然后您应该使用覆盖函数(内联)一个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。

答案 1 :(得分:0)

指明您的安全意义,无论如何,iPhone上的strncpy与其他平台上的安全一样安全。

由于您需要strncpy我猜您没有使用NSString,因此我认为使用它时没有任何问题。