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

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

}

感谢您的宝贵时间。

最佳答案

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

但是,您在下次尝试阅读某些内容时遇到信息留在输入缓冲区中的问题 - 这是用户会觉得非常烦人的内容,输入类似 hello 的内容again 并将其视为两个独立的输入,如 hello againfgets 没有给出它在行尾之前停止检索输入的指示,因此,就您的代码而言,一切都很好。

您需要注意的主要事项(重新输入缓冲区溢出)至少是 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;
}

然后,做一些基本的测试:

pax> ./prog
Enter string> [CTRL-D]
No input

pax> ./prog
Enter string> x
OK [x]

pax> ./prog
Enter string> hello
OK [hello]

pax> ./prog
Enter string> hello from earth
Input too long [hello fro]
Hit ENTER to check remains> [ENTER]
Excess []

pax> ./prog
Enter string> i am pax
OK [i am pax]

关于c - 这容易受到堆栈溢出的影响吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5130723/

相关文章:

c - for 循环在 C 中给出意想不到的结果

c - ncurses 位 block 传输/缓冲区

c - sscanf 和尾随字符

CSS - 如何在不更改任何其他内容的情况下删除第二个垂直滚动条?

c - 如何将基于 C 的语言添加到 GCC

c - 为什么更大的堆栈会使 .bss 增加 4 倍?

java - java中使用单栈实现队列

c++ - 基于堆栈缓冲区的 STL 分配器?

c - 这段代码容易受到缓冲区溢出的影响吗?

html - 有什么方法可以阻止特定文本行溢出到下一行?