问题
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
char first_name[20];
char last_name[20];
int student_num;
char debts[1];
printf("Enter name:");
scanf("%s", first_name);
printf("Enter lastname:");
scanf("%s", last_name);
printf("Enter six bits length student ID:");
scanf("%d", &student_num);
printf("Do you have debts for university [Y/N]?");
scanf("%s", debts);
printf("\nYour name is %s %s.\n", first_name, last_name);
printf("Your Student ID is %d.\n", student_num);
printf("Debts: %s.\n", debts);
return (EXIT_SUCCESS);
}
How to avoid buffer overflow in this code? I want my code to produce such an output:
Enter name:Enescekilokoneyasharrontannamyantoniaaquin
Enter lastname:Basenau
Enter six bits length student ID:456789
Do you have debts for university [Y/N]?YES
Your name is **Enescekilokoneyashar** (only 20 bits from name input) *Basenau*.
Your Student ID is **393299**.
Debts: **Y**.
Process returned -1073741819 (0xC0000005) execution time : 36.336 s
Press any key to continue.
I have tried to use:
scanf("%19s", first_name);
But it does not work as I expect. I need to find some another way to validate input parameters to prevent buffer overflow attack and limit input to buffers size.
回答1:
You can maintain the use of scanf
but you need to limit the size of what it can take to the size of the destination buffer, something like:
scanf(" %19[^\n]", first_name); //last destination buffer element is for null byte
Note that this specifier can parse spaces so you can take an input with more than one word.
It will, however, leave a \n
character in the stdin
buffer, or the remaining characters that were not parsed in case you input a larger string, so you need to clear it every time you want to parse a new input, you can make a handy function that you can call when you need such clearence, making it a pattern:
void clear_buffer(){
int c;
while ((c = getchar()) != '\n' && c != EOF){
continue;
}
}
Your char debts[1]
buffer is also problematic, it's too small to store a string, it needs to have at least 2 characters to be able to store the null terminator:
char debts[2];
And the call will be:
clear_buffer();
scanf(" %1[^\n]", debts);
Lastly you should verify the return of scanf
, for instance, in scanf("%d", &student_num)
, if you input alphabetical characters instead of digits, the function will fail to parse and return 0, you can also make it parse at most 6 digits, something along the lines of:
clear_buffer();
if(scanf("%6d", &student_num) == 0){ // %6d limit the input to 6 digits
//handle error
}
Live demo
回答2:
If you are on windows you can use scanf_s() as described in the Microsoft documentation here. There is also an example given:
char s[10];
scanf_s("%9s", s, (unsigned)_countof(s));
来源:https://stackoverflow.com/questions/64368589/how-to-avoid-buffer-overflow-using-scanf