当我尝试编译使用gets()
GCC函数的C代码时,
我明白了
警告:
(.text + 0x34):警告:`gets'函数很危险,不应该使用.
我记得这与堆栈保护和安全性有关,但我不确定为什么?
有人可以帮我删除这个警告并解释为什么会有这样的使用警告gets()
?
如果gets()
是如此危险,为什么我们不能删除它?
我有一个接受字符串的函数,即:
void log_out(char *);
Run Code Online (Sandbox Code Playgroud)
在调用它时,我需要动态创建一个格式化的字符串,如:
int i = 1;
log_out("some text %d", i);
Run Code Online (Sandbox Code Playgroud)
我如何在ANSI C中执行此操作?
只是,因为sprintf()
返回一个int,这意味着我必须编写至少3个命令,如:
char *s;
sprintf(s, "%d\t%d", ix, iy);
log_out(s);
Run Code Online (Sandbox Code Playgroud)
有什么方法可以缩短这个吗?
snprintf是否始终为null终止目标缓冲区?
换句话说,这是否足够:
char dst[10];
snprintf(dst, sizeof (dst), "blah %s", somestr);
Run Code Online (Sandbox Code Playgroud)
或者你必须这样做,如果somestr足够长?
char dst[10];
somestr[sizeof (dst) - 1] = '\0';
snprintf(dst, sizeof (dst) - 1, "blah %s", somestr);
Run Code Online (Sandbox Code Playgroud)
我对标准所说的以及一些流行的libc可能做的不是标准行为感兴趣.
strncpy()
据说可以防止缓冲区溢出.但是如果它在没有null终止的情况下防止溢出,那么随后的字符串操作将会溢出.所以为了防止这种情况,我发现自己在做:
strncpy( dest, src, LEN );
dest[LEN - 1] = '\0';
Run Code Online (Sandbox Code Playgroud)
man strncpy
得到:
strncpy()函数类似,只是复制了不超过n个字节的src.因此,如果src的前n个字节中没有空字节,则结果将不会以空值终止.
没有null终止看似无辜的东西,如:
printf( "FOO: %s\n", dest );
Run Code Online (Sandbox Code Playgroud)
......可能会崩溃
是否有更好,更安全的替代品strncpy()
?
我正在使用一些代码,这些代码广泛使用返回指向静态局部变量的指针的习惯用法.例如:
char* const GetString()
{
static char sTest[5];
strcpy(sTest, "Test");
return sTest;
}
Run Code Online (Sandbox Code Playgroud)
我认为这是安全的吗?
PS,我知道这是做同样事情的更好方法:
char* const GetString()
{
return "Test";
}
Run Code Online (Sandbox Code Playgroud)
编辑: 道歉,功能签名当然应该是:
const char* GetString();
Run Code Online (Sandbox Code Playgroud) strtok
我需要注意哪些特性是不安全的(在缓冲区溢出方面)?
对我来说有点奇怪的是strtok_s
(在Visual C++中它是"安全的")有一个额外的"上下文"参数,但看起来它在其他方面是相同的......它是相同的,还是它实际上是不同的?
std :: strlen不处理不是\ 0终止的c字符串.它有安全版吗?
PS我知道在c ++中应该使用std :: string而不是c字符串,但在这种情况下,我的字符串存储在共享内存中.
编辑
好的,我需要补充一些解释.
我的应用程序从共享内存(有一定长度)获取一个字符串,因此它可以表示为一个字符数组.如果库中有一个错误写入此字符串,则该字符串不会被终止,并且strlen可能会失败.
我想从标准输入中读取整行,包括两个单词之间的空格.
当使用get on gcc时,我收到以下消息:
send.c:(.text+0x2a): warning: the `gets' function is dangerous and should not be used.
Run Code Online (Sandbox Code Playgroud)
什么是更好的选择?
可能有人给我解释一下什么样的差异之间存在着strtok()
和strsep()
?它们的优点和缺点是什么?为什么我会选择一个而不是另一个.
在上一个问题的模型中,我询问了所谓的安全库折旧,我发现自己同样对于为什么fopen()
应该被弃用感到困惑.
该函数接受两个C字符串,并返回FILE*ptr,或者在失败时返回NULL.线程安全问题/字符串溢出问题在哪里?或者是别的什么?
提前致谢