这容易受到堆栈溢出的影响吗?

时间:2011-02-27 01:07:18

标签: c stack overflow

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");

}

感谢您的时间。

3 个答案:

答案 0 :(得分:4)

如果输入的字符多于安全存储的字符数,则不会出现缓冲区溢出问题,因为fgets限制输入。它还添加了一个空终止符(当然,假设缓冲区大小大于0)。

但是,当你下次尝试阅读某些东西时,在输入缓冲区中留下信息时出现问题 - 用户会觉得非常烦人,输入{{1}之类的东西并将其视为两个单独的输入,如hello againhello 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)

不,它不容易出现堆栈溢出。

您是否有可能混淆堆栈溢出和缓冲区溢出?

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

答案 2 :(得分:0)

fgets最多读取的数量小于指定的字节数,并确保读取的字符串以空值终止。因此,只要您传递正确的大小,它应该没问题(尽管字符串可能不会以换行符结尾)。