Ncurses / C / C ++:使用getstr()并防止溢出(必须有更好的方法来执行此操作)

时间:2014-02-12 17:58:18

标签: c++ c ncurses buffer-overflow

我目前正在进入我的第一个完整的C ++项目,而且我遇到了Ncurses。

getstr()需要一个char数组作为输入,但是有了这个,就没有办法防止缓冲区溢出。让我假装我正在使用此输入来获取名称。我的代码将是以下内容:

int main(){
    char* nameTemp = new char[160];
    initscr();
    getstr(nameTemp);
    endwin();
    delete nameTemp;
    return 0;
}

但是如果用户决定使用超过160个字符作为他的名字,会发生什么?我收到错误,程序失败。 除了创建庞大的Char数组之外,有没有办法解决程序中的这种致命缺陷? 感谢。

注意:我正在使用带有g ++的Ubuntu 12.04

4 个答案:

答案 0 :(得分:6)

使用:

int getnstr(char *str, int n);

最多读取n个字符。

答案 1 :(得分:5)

来自http://www.tldp.org/HOWTO/NCURSES-Programming-HOWTO/scanw.html

  

7.3。 getstr()函数类
  ......实质上,此功能执行的任务与完成的任务相同   通过一系列调用getch()直到换行,回车或   收到文件结尾。 ...

因此,虽然它不是一个完美的解决方案,但您可以在循环中使用getch(),直到到达char数组的末尾或者直到用户键入换行符。

char* nameTemp = new char[160];
int i = 0;
// don't put anything in the last index, to ensure a properly ended string
while (i < 159) {
    nameTemp[i] = getch();
    if (nameTemp[i] == '\n') {
        break;
    } else if (nameTemp[i] == '\b') {
        nameTemp[i] = 0;
        i--;
        nameTemp[i] = 0;
        i--; // cancel out the increment at end of loop
    }
    i++;
}
nameTemp[i] = 0; // the \n or tempName[159], whichever comes first

答案 2 :(得分:1)

如何使用getch一次获取一个角色?通过这种方式,您可以完全控制您正在阅读的内容:

    std::string get_line()
    {
      std::string result;
      while(true)
      {
        int c = getch();
        if(c == ERR || c == '\n') return result;
        else result += c; 
      }
    }

例如。 (此代码未经测试)。

答案 3 :(得分:0)

在Windows上,您可以动态分配50MB缓冲区。这将确保在下一个Patch Tuesday之前溢出缓冲区是不现实的,因此无论如何你的盒子都会重新启动:)