如何在没有缓冲区溢出问题的情况下使用strncat?

时间:2011-08-01 20:22:58

标签: c string buffer-overflow

我有一个缓冲区,我正在做很多strncat。我想确保我永远不会溢出缓冲区大小。

char buff[64];

strcpy(buff, "String 1");

strncat(buff, "String 2", sizeof(buff));

strncat(buff, "String 3", sizeof(buff));

而不是sizeof(buff),我想说一些buff-xxx。我想确保我永远不会覆盖缓冲区

5 个答案:

答案 0 :(得分:16)

考虑现有字符串和空终止符的大小

#define BUFFER_SIZE 64
char buff[BUFFER_SIZE];

//Use strncpy
strncpy(buff, "String 1", BUFFER_SIZE - 1);
buff[BUFFER_SIZE - 1] = '\0';

strncat(buff, "String 2", BUFFER_SIZE - strlen(buff) - 1);

strncat(buff, "String 3", BUFFER_SIZE - strlen(buff) - 1);

答案 1 :(得分:11)

为什么不使用snprintf?与strncat不同,它需要缓冲区的大小,但更重要的是,没有隐藏的O(n)。

Strcat需要在它连接的每个字符串上找到空终止符,并且每次都通过整个缓冲区来查找结束。每次字符串变长,strcat都会变慢。另一方面,Sprintf可以跟踪结束。你会发现

snprintf(buf, sizeof buf, "%s%s%s", "String1", "String2", "String3");

通常是一个更快,更易读的解决方案。

答案 2 :(得分:6)

在您的原始代码中使用strncat函数的方式实际上适用于其他函数:strlcat(注意l而不是n)。 strlcat函数不是标准函数,但它是strncat的常用实现替代函数。 strlcat期望整个目标缓冲区的总大小作为其最后一个参数。

同时,strncat期望目标缓冲区的剩余未使用部分的大小作为其第三个参数。因此,您的原始代码不正确。

我建议不要对strncpy进行可怕的滥用,并使用strlen调用进行明确的重新扫描(Joe的答案中都存在这两个问题),您要么使用提供的实现{{1或者自己实现一个(如果你的实现不提供strlcat)。

http://en.wikipedia.org/wiki/Strlcpy

答案 3 :(得分:3)

这是最好的方法。 sizeof()只是给你指向数据的指针的大小,如果你不在本地分配它(在这种情况下你确实在本地进行了分配,但是这样做更好,如果代码被重新分解它会工作) 。

#define MAXBUFFSIZE 64

char buff[MAXBUFFSIZE];

buff[0] = 0;  // or some string

strncat(buff, "String x",MAXBUFFSIZE - strlen(buff) - 1);

答案 4 :(得分:1)

霍根已经足够满满地回答了这个问题;但是,如果你担心strcat(...)中的缓冲区溢出,你应该同样担心所有其他字符串函数中的缓冲区溢出。

使用strnlen(...)strncpy(...)确保您保持在缓冲区内。如果您没有strnlen(...)功能,请写下来。