C提示被覆盖

问题描述:

我是C新手,遇到一个奇怪的问题。C提示被覆盖

此代码是一个更大的程序的一部分,但问题是在这里,但我似乎无法弄清楚。

#include <stdio.h> 
#include <string.h> 
#define WORDSIZE 512 

int read_stdNum(const char prompt[], char store[], size_t n) { 
    char inHold[WORDSIZE]; 
    char process[10]; 
    int status = 0; 

    while (1) { 
     fprintf(stderr, "%s", prompt); 

     if(fgets(inHold, WORDSIZE, stdin) == NULL) { 
      return 0; 
     } 

     sscanf(inHold, "%s", process); 

     status = sscanf(process, "%s", store); 

     if (status > 0 && strlen(store) == n) { 
      return 1; 
     } else if (status == -1) { 
      continue; 
     } else { 
      continue; 
     } 
    } 
} 

int main(void) { 
    char arrow[] = "\n==> "; 
    char stdNum[10]; 

    printf("%s\n", "store_student called."); 

    fprintf(stderr, "%s", "\nEnter a student number (axxxxxxxx)\n"); 
    read_stdNum(arrow, stdNum, 9); 
    return 0; 
} 

程序会要求用户输入,这里的测试是针对程序截断多余的数字,但是当我输入类似“a123456789101112131415”,输出的是什么,工作正常,但随后的提示符会被覆盖并且提示符如下所示:

==> a123456789101112131415 
131415_ 

下划线是我仍然可以输入的位置。 字符数组'进程'也存储超过9个字符。 我问过我的一些同学,还有一个人说他在电脑上工作的很好。 我知道我会因为愚蠢而发火,但我真的很想知道为什么这不起作用。 谢谢。

+0

你传递'9'作为字符串的长度看,根据你的输入你只能输入'6'字符。这意味着'strlen(store)!= n'。现在想想几分钟。然后在一个调试器中运行你的程序并逐行浏览代码,看看实际发生了什么。希望它能给你一些线索,说明你的问题可能是什么。 –

+4

您的'sscanf'调用可能会溢出缓冲区。 – interjay

scanf用“%s”功能可能是不安全的,并创建缓冲区溢出(它可能写入多个字节到除了分配给弦的空间输出字符串,重写一些有用的数据),检查https://cwe.mitre.org/data/definitions/120.html“CWE-120:缓冲不检查输入(“经典缓冲区溢出”)” &例子的尺寸的复印1

https://en.wikipedia.org/wiki/Scanf_format_string#Vulnerabilities

这意味着,如果没有长的%s占位符使用说明符一对于缓冲区溢出本质上是不安全的和可利用的。

scanf文档具有大约s格式使用的一些要求(阵列必须足够长)http://man7.org/linux/man-pages/man3/scanf.3.html

s 
      Matches a sequence of non-white-space characters; the next 
      pointer must be a pointer to the initial element of a 
      character array that is long enough to hold the input sequence 
      and the terminating null byte ('\0'), which is added 
      automatically. The input string stops at white space or at 
      the maximum field width, whichever occurs first. 

的类似scanf函数的更安全的使用量是用“最大字段宽度“,如%9sm用于动态内存分配。

(您与strlen检查是为时已晚; sscanf已经没有串的溢/覆盖,因为它有对长度没有限制阅读。)

+0

非常感谢,我明白了! – 2f1