scanf field width string overflow

2019-06-17 17:40发布

问题:

Which one of the following is safe regarding buffer overflow?

char buf[10] = {0};
scanf("%10s", buf);

or

char buf[10] = {0};
scanf("%9s", buf);

From what I've read I'm going for the second (sizeof minus one), but the matter is quite subtle and I've seen code suggesting either. Any volunteer to quote the standard?

回答1:

The C standard states that:

An input item shall be defined as the longest sequence of input bytes (up to any specified maximum field width, which may be measured in characters or bytes dependent on the conversion specifier) which is an initial subsequence of a matching sequence.

That is, the maximum field width represents how many characters there can be in the input. The extra zero value at the end is not part of the input and needs an additional space.

The GNU libc manual makes this point explicit:

String input conversions store a null character to mark the end of the input; the maximum field width does not include this terminator.

So, the only safe version is scanf("%9s", buf).



回答2:

char buf[10] = {0};
scanf("%10s", buf);

is unsafe. You have to take into account the string null terminator.

char buf[10] = {0};
scanf("%9s", buf);

is safe.



标签: c input scanf