void gctinp (char *inp, int siz)
{
puts ("Input value: ");
fgets (inp, siz, stdin);
printf ("buffer3 getinp read %s", inp);
}
根据我的阅读,当你想限制输入的大小时,应该使用fgets。那么这段代码不应该是易受攻击的吗?
它被称为:
int main (int argc, char *argv[])
{
char buf[16];
getinp (buf, sizeof (buf));
display (buf);
printf ("buffer3 done\n");
}
感谢您的时间。
答案 0 :(得分:4)
如果输入的字符多于安全存储的字符数,则不会出现缓冲区溢出问题,因为fgets
限制输入。它还添加了一个空终止符(当然,假设缓冲区大小大于0)。
但是,当你下次尝试阅读某些东西时,将在输入缓冲区中留下信息时出现问题 - 用户会觉得非常烦人,输入{{1}之类的东西并将其视为两个单独的输入,如hello again
和hello ag
。并且ain
没有指示它在行结束之前停止检索输入,因此,就您的代码所知,一切都很好。
您需要注意的主要事项(输入上的缓冲区溢出)至少是fgets
,其中包含无限制的scanf
格式字符串和%s
,它没有限制大小参数,两者都不在您的代码中。
如果您正在寻找具有大小限制,提示和缓冲区清除功能的更强大的输入解决方案,请查看此代码,该代码提供了所有这些功能:
gets
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
然后,做一些基本测试:
// Test program for getLine().
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
rc = getLine ("Hit ENTER to check remains> ", buff, sizeof(buff));
printf ("Excess [%s]\n", buff);
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
答案 1 :(得分:1)
答案 2 :(得分:0)
fgets最多读取的数量小于指定的字节数,并确保读取的字符串以空值终止。因此,只要您传递正确的大小,它应该没问题(尽管字符串可能不会以换行符结尾)。