Why can char name [1] contain more than 1 character?

I did some research on the topic when I came across this situation. Assume the following C code:

#include <stdio.h> int main() { char name[1]; scanf("%s",name); printf("Hi %s",name); return 0; } 

I compiled with -fno-stack-protector and tested it with input over 1, like John , and to my surprise, it works!
Should it cause a segmentation error when the input signal is greater than 1?
He eventually broke down with Alexander as an input (9), but he works with anything less than 9.
Why does it work with inputs longer than the length of an array of names?
PS: I use Ubuntu (64-bit), gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1 ~ 14.04) and CLion as an IDE.

+4
source share
2 answers

This behavior is undefined. Your program has a buffer overflow because it allocates exactly one character, which is enough to store an empty string with zero termination.

However, next to your buffer there is memory that was not allocated to your program. scanf puts your input into this memory because it does not know how long your string buffer is. This is a great danger and a source of countless hacker attacks when a predetermined sequence of bytes is placed on your line, in the hope of redefining some vital elements and, ultimately, gaining control.

This is why using %s without specifying a size is dangerous. You should always add a limit on the size of %s , otherwise your program will be prone to buffer overflows.

 char name[120]; scanf("%119s",name); 

This program is safe because even if a malicious user enters more than 120 characters, scanf will ignore the entire past of the 119th character, as specified in the %119s format.

+6
source

The size and type of the variable in which you store the input has nothing to do with scanf .

scanf only the address (pointer) is passed, where you need to enter the input that it receives from the user.

Smart compilers now warn you if the format string passed to scanf does not match the type of parameters, but in principle you can even declare name as an integer:

 int name; 

and it will contain an input line well enough, up to three characters (the fourth for the end of the line, i.e. zero) if the size of int is 32 bits, i.e. 4 bytes

The fact that it works is a complete failure, since the input stored in scanf goes beyond the end of the allocated buffer for it ( name ).

Note: highlighting only one character for a line will never work even for input lines of only one character. You always need to consider the EOS that is used to terminate them. Therefore, name must be declared as char name[2]; , at least.

+1
source

All Articles