Pop quiz, which of these is safe, given "char buf[80]" and arbitrary user input in argv[1]?<p><pre><code> gets(buf);
scanf("%s", buf);
strcpy(buf, argv[1]);
scanf("%80s", buf);
strncpy(buf, argv[1], 80);
snprintf(buf, 80, argv[1]);
</code></pre>
----<p>The delightful answer is <i>none of them</i>. The first three have no bounds checking at all, meaning that they will happily overflow the buffer to an arbitrary extent (gets, at least, will usually trigger a warning on modern compilers). The next two have off-by-one errors: scanf will write a NUL byte out of bounds (and that's exploitable! <a href="https://googleprojectzero.blogspot.com/2014/08/the-poisoned-nul-byte-2014-edition.html" rel="nofollow">https://googleprojectzero.blogspot.com/2014/08/the-poisoned-...</a>) while strncpy will fail to NUL-terminate the string. The last one uses the right buffer length, but treats user input as a format string and can leak memory contents or produce arbitrary memory corruption with the %n format specifier.<p>C string handling practically invites off-by-one errors and horrible security practices out-of-the-box.