I'm new to C and I encountered a weird problem.
This code is part of a bigger program, but the problem is within here but I can't seem to figure it out.
#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;
}
The program asks for user input, and the test here is for the program to truncate the extra digits, but when I type something like " a123456789101112131415
", the output is nothing, which works fine, but then the prompt gets over written and the prompt looks like this:
==> a123456789101112131415
131415_
The underscore is where I can still enter in input. The the character array 'process' is also storing more than 9 characters. I've asked some of my classmates, and also one of them said that it worked fine on his computer. I know I'm going to get flamed for being dumb but I really want to know why this is not working. Thanks.
scanf
function with " %s
" may be unsafe and create buffer overflow (it may write more bytes into output string than the space allocated for the string, overwriting some useful data), check https://cwe.mitre.org/data/definitions/120.html "CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')" & example 1
https://en.wikipedia.org/wiki/Scanf_format_string#Vulnerabilities
This means that uses of
%s
placeholders without length specifiers are inherently insecure and exploitable for buffer overflows.
Documentation of scanf
has some requirements about s
format usage (array must be long enough) 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.
The safer usage of scanf-like functions is to use "maximum field width" like %9s
or m
for dynamic memory allocation.
(Your check with strlen
is too late; sscanf
already did the overflow/overwrite of string because it had no limit on length to read.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.