Insecurity analysis of scanf function

int scanf(char*,...) is its function declaration. Among them, only the first parameter is required to be char*, which is a string, and there are no restrictions on the type and number of other parameters, which has security risks. For example:
scanf("%d %c",&i,&ch); If the data input from the keyboard is: 30 A? Then the value of the variable ch is a space character instead of the character'A'. This kind of error is very hidden, so it is recommended that readers try not to use the scanf function to input a set of different types of data values ​​including character data from the keyboard to avoid inexplicable errors. Also the following example:

#include <cstdio>
int main()
{     char a;     while( scanf("%c",&a), a!='\n')         printf("%c", a);     printf( "\n");     return 0; } It can be seen that the scanf function can accept any keyboard input. If the input length exceeds the buffer given by the application, other data areas will be overwritten. This is called "stack Overflow" or "buffer overflow". And the scanf function has three characteristics: 1. When fetching data, it will stop when it encounters a space, carriage return, and TAB; 2. The scanf function reads data from the input stream buffer instead of buffering from the keyboard (terminal). Read the value of the area. When reading a carriage return\n, it will end, and carriage return\n will be read into the input buffer data stream, so that the second reading function will read the carriage return in the input buffer\n away, There is no waiting for a second input from the keyboard. 3. When scanf reads the string, it will discard the last carriage return.











From the second feature, we can see that in the above example, if the input is very long, after the end with'\n','\n' will cover the following data area, causing buffer overflow.

Attachment: Scanf function summary:
1. An important parameter in scanf function: %[] means to read in a set of characters, %[] specifically refers to those characters limited by the set, such as %[AZ] means input uppercase Characters, once encountered non-conformance, the input will stop, but the read string can contain spaces.
2. The general format of the scanf() function is: scanf("format string", the first address table of the input item) The general format of scanf
control is: %[*][width][F|N][h|l ]

    The control character in the type character [] is optional 
    "*" means that no variable is assigned after the input item is read, that is, the input value is skipped. This is still useful in reducing memory costs. Unneeded characters are skipped directly, so as not to apply for useless variable space. 
    "Width" means the length of the input and read characters. For integers, it means intercepting the number of the corresponding width and assigning it to Corresponding variables in the following list; for the character type, the first character is assigned to the corresponding variable after reading the characters of the corresponding length, and the rest are automatically discarded. For example, scanf("%2d%3d",&a, &b); if the input is 12345, assign 12 to a and 45 to b; scanf("%2c%3c",&a, &b); if the input is 12345 Assign '1' to a, and assign '3' to b. 
    F, N, h, and l represent far pointer, near pointer, short integer, and long integer, respectively. The corresponding control character for _int64 is ll or I64 
    " Type character" 

Some skills
for string reading There are also some useful controls for input strings.
For example, it is often necessary to read a line of string, and this string of characters may contain blank characters such as spaces and tabs.
If you use %s directly , it is No, so some people think of using gets(), of course this is also an option,
but people who know C basically know that gets() is a very dangerous function and it is difficult to control,
especially with scanf( ) When used alternately, the disadvantages of the former are more at a glance, so gets() is generally not recommended. Its
practical %[^/n] can solve this problem well.
^ means "not", that is, read in The character after it ends reading.
If you want to read a line of string like this, you can directly use scanf("%[^/n]%*c",str);.
The function of %*c is to read /n, otherwise it will always be / n.
All controls that work on %s can use %[]. For
example, %[0-9] means read-only characters from '0' to '9', and %[a-zA-Z] means read-only The letter,
'-' is the range connector, of
course, you can also directly list the characters you need to read. The reason why the range connector is used to read the letters above is because it
is too troublesome to enter 52 characters.
If you only need to read "abc "The characters inside can use %[abc] (or %[cab], %[acb], %[ac], %[ca].....),
if you want to read characters outside a certain range Add a'^' in front of the string,


88888,3245;34:123. To
let you output all the numbers in it, you can use the following code:
#include <stdio.h>
bool skip(){     scanf("%*[^0-9]");     return true; } int main(){     int n;     while (skip() && scanf("%d", &n)!=EOF)         printf("%d/n", n);     return 0; }








https://bbs.csdn.net/topics/390548599

Guess you like

Origin blog.csdn.net/tjcwt2011/article/details/112799845