C Strings and my slow descent to madness
Pop quiz, which of these is safe, given &quot;char buf[80]&quot; and arbitrary user input in argv[1]?<p><pre><code>    gets(buf);
    scanf(&quot;%s&quot;, buf);
    strcpy(buf, argv[1]);
    scanf(&quot;�s&quot;, 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&#x27;s exploitable! <a href="https:&#x2F;&#x2F;googleprojectzero.blogspot.com&#x2F;2014&#x2F;08&#x2F;the-poisoned-nul-byte-2014-edition.html" rel="nofollow">https:&#x2F;&#x2F;googleprojectzero.blogspot.com&#x2F;2014&#x2F;08&#x2F;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.