如何使以下代码能够抵御缓冲区溢出和无效输入? 您能编辑一下我应该更改哪些部分吗?
#include <stdio.h>
#include <string.h>
void password();
int main()
{
password();
return 0;
}
void password()
{
int number;
printf("PLEASE ENTER YOUR PASSWORD \n");
while (1){
if((scanf("%d",&number)) != 1)
{
printf("wrong input\n");
}
else {
if (number==999)
printf("\n----PASSWORD IS CORRECT-----\n\n");
break;
}
else
printf("\n Please enter a valid password (integer)\n");
}
}
}
最佳答案
对于您的代码,您正在将整数值解析为整数变量。因此,您的代码不包含缓冲区溢出漏洞。
对于格式化,您的代码可以忽略数字值之前的输入(例如字母),但它无法检查可解析整数值之后是否存在无效输入。因此,999abc 的字符串将适用于您的原始代码。
为了防止这种情况,我让 scanf() 在整数值后解析 1 个附加字符。该字符可以是任何东西,只是不是行尾字符。如果 scanf() 可以读取该字符,则意味着输入无效。无效输入的一些示例包括“999”、“999abc”和“999-assdf”。
因此,如果整数值前面有无效字符或只有无效输入,则 scanf() 返回值为 0;如果整数值后面有无效字符,则返回值为 2;如果只是要读取的整数,则返回值为 1 。因此,对于有效整数值的成功解析情况,scanf() 返回值应该仅为 1。
当失败时,必须刷新 stdin。因此,我用 getchar() 刷新标准输入。否则,那些无法解析的字符将被下一个 scanf() 读取。
更新:我刚刚记得您也可以在没有数组的情况下读取该字符。因此,我更新了答案代码。此外,scanf() 最明显的麻烦有时可能成为漏洞,那就是在解析数字时,scanf() 不检查溢出,并且无法修复该问题。除非你将 int32 的数字解析数量限制为 9 位。虽然 int32 有 10 位数字,但仅 9999999999 就可以多次溢出。因此,在下面的示例代码中,给出该数字 2014339662823,它将传递您的密码 999。
有几种方法可以解决溢出问题,其中之一是将数字解析为更高的数据类型。例如,如果您需要 32 位的 int 值。将其解析为 int64。然后检查结果。但是如果您想将数字解析为最高数据类型会发生什么。如果可用的话,就像 int128 一样。那么唯一的办法就是将输入解析为字符串然后自己检查并解析为int类型。
#include <stdio.h>
#include <string.h>
void password();
int main(){
password();
return 0;
}
void password(){
int number, c;
char voidChar;
printf("PLEASE ENTER YOUR PASSWORD \n");
while (1){
if((scanf("%d%[^\n]c",&number, &voidChar)) != 1){
printf("Wrong input(Integer Only):\n");
while((c = getchar()) != EOF && c != '\n');
continue;
} else {
if (number==999){
printf("\n----PASSWORD IS CORRECT-----\n\n");
break;
}
printf("\n Please enter a valid password\n");
}
}
}
因为你不知道什么是缓冲区溢出。下面的代码演示了缓冲区溢出的一个简单示例。运行下面的代码并输入“abcdefghijklmnopqrstuvwxyz012456Hello_World”(不带引号)。运行后,您仍然可以释放为“user”变量分配的内存。但是,您将无法释放为“thisWillChange”变量分配的内存。在 scanf() 写入超出 malloc 为“user”变量保留的内存范围后,其内存块被损坏。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char * user = (char * ) malloc(10);
char * thisWillChange = (char *) malloc(10);
puts("Please enter your password");
scanf("%s", user);
puts(thisWillChange);
// abcdefghijklmnopqrstuvwxyz012456Hello_World
return 0;
}
关于c - 修复代码以缓解缓冲区溢出和无效输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59291939/