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个字符。 我问过我的一些同学,还有一个人说他在电脑上工作的很好。 我知道我会因为愚蠢而发火,但我真的很想知道为什么这不起作用。 谢谢。
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函数的更安全的使用量是用“最大字段宽度“,如%9s
或m
用于动态内存分配。
(您与strlen
检查是为时已晚; sscanf
已经没有串的溢/覆盖,因为它有对长度没有限制阅读。)
非常感谢,我明白了! – 2f1
你传递'9'作为字符串的长度看,根据你的输入你只能输入'6'字符。这意味着'strlen(store)!= n'。现在想想几分钟。然后在一个调试器中运行你的程序并逐行浏览代码,看看实际发生了什么。希望它能给你一些线索,说明你的问题可能是什么。 –
您的'sscanf'调用可能会溢出缓冲区。 – interjay