<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Unsafe Functions In C And Their Safer Replacements: Strings Part I</title>
	<atom:link href="http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html/feed" rel="self" type="application/rss+xml" />
	<link>http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html</link>
	<description>Making Your Code Faster, Stronger, Safer…</description>
	<lastBuildDate>Thu, 18 Feb 2010 05:11:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Zombie No. 5</title>
		<link>http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html#comment-694</link>
		<dc:creator>Zombie No. 5</dc:creator>
		<pubDate>Mon, 06 Apr 2009 20:10:03 +0000</pubDate>
		<guid isPermaLink="false">http://www.safercode.com/blog/?p=14#comment-694</guid>
		<description>strcpy() is certainly not implemented as you claim because it actually works for empty strings (&quot;&quot;) unlike your code.</description>
		<content:encoded><![CDATA[<p>strcpy() is certainly not implemented as you claim because it actually works for empty strings (&#8220;&#8221;) unlike your code.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Zombie No. 5</title>
		<link>http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html#comment-669</link>
		<dc:creator>Zombie No. 5</dc:creator>
		<pubDate>Sun, 05 Apr 2009 14:58:46 +0000</pubDate>
		<guid isPermaLink="false">http://www.safercode.com/blog/?p=14#comment-669</guid>
		<description>Dummy00001: You sure know how to reduce your credibility to zero and make people not listen to you.

&quot;*BSD folks&quot; are no more erratic than GNU, Linux or Solaris folks. In fact, they tend to be much more conservative and emphasize clean design. After all, GNU and Linux are nothing but a glorified BSD clone. It&#039;s easy to avoid mistakes by taking advantage of decade long experience. Not that this would be automatic. Actually the GNU and Linux folks repeated a lot mistakes they could have avoided by learning from BSD history.

Anyway, there are actually two versions of snprintf(). A newer POSIX variant and one that has been provided by Solaris as an extension long before. The latter returns the resulting - possibly truncated - string length. The same you get by using strlen() with the result. The POSIX variant returns the length of the string if the buffer had been sufficient. So on truncation you could use that value to allocate a sufficient buffer and then repeat the call with this buffer to get an untruncatened string.

Also note that &quot;%*.s&quot; takes an &quot;int&quot; and not size_t as parameter and also returns an int. So it is limited to strings of a maximum length of INT_MAX. Something many 32-bit developers tend to ignore but is a easily an exploitable vulnerability nowadays on 64-bit systems with many gibibytes of RAM.

Last but not least, the printf family is a rather high-level interface and has - considering the alternatives - a lot of overhead internally.

In my opinion, a professional seasoned C developer will rarely rely on these silly C library functions except in small, trivial pieces of code. Rather they&#039;ll use - or even roll their own - string library that takes care of memory allocation, truncation prevention and optimizations. Also strlcpy(), strncpy() etc. usually have subtle semantics - which you know if you bother reading their specifications - that are not desirable in many contexts when you actually use them. Examples:

strncpy() pads the whole destination buffer with NULs but does not guarantee NUL-termination. strncat() DOES guarantee NUL-termination. The padding may seem stupid and an inefficient but it makes a lot of sense in the intented contexts. Nobody ever claimed these are general purpose functions. Hence, don&#039;t be shy to roll your own functions which make more sense in your context. Of course, make sure you specify them cleanly including corner-cases and test them. In C strings are not something abstract which is both an advantage and disadvantage.

strlcpy() can&#039;t accept non-terminated data as source string and will also traverse the whole source string even if only a tiny part is copied. The latters makes it in efficient and an the former even insecure in many contexts.</description>
		<content:encoded><![CDATA[<p>Dummy00001: You sure know how to reduce your credibility to zero and make people not listen to you.</p>
<p>&#8220;*BSD folks&#8221; are no more erratic than GNU, Linux or Solaris folks. In fact, they tend to be much more conservative and emphasize clean design. After all, GNU and Linux are nothing but a glorified BSD clone. It&#8217;s easy to avoid mistakes by taking advantage of decade long experience. Not that this would be automatic. Actually the GNU and Linux folks repeated a lot mistakes they could have avoided by learning from BSD history.</p>
<p>Anyway, there are actually two versions of snprintf(). A newer POSIX variant and one that has been provided by Solaris as an extension long before. The latter returns the resulting &#8211; possibly truncated &#8211; string length. The same you get by using strlen() with the result. The POSIX variant returns the length of the string if the buffer had been sufficient. So on truncation you could use that value to allocate a sufficient buffer and then repeat the call with this buffer to get an untruncatened string.</p>
<p>Also note that &#8220;%*.s&#8221; takes an &#8220;int&#8221; and not size_t as parameter and also returns an int. So it is limited to strings of a maximum length of INT_MAX. Something many 32-bit developers tend to ignore but is a easily an exploitable vulnerability nowadays on 64-bit systems with many gibibytes of RAM.</p>
<p>Last but not least, the printf family is a rather high-level interface and has &#8211; considering the alternatives &#8211; a lot of overhead internally.</p>
<p>In my opinion, a professional seasoned C developer will rarely rely on these silly C library functions except in small, trivial pieces of code. Rather they&#8217;ll use &#8211; or even roll their own &#8211; string library that takes care of memory allocation, truncation prevention and optimizations. Also strlcpy(), strncpy() etc. usually have subtle semantics &#8211; which you know if you bother reading their specifications &#8211; that are not desirable in many contexts when you actually use them. Examples:</p>
<p>strncpy() pads the whole destination buffer with NULs but does not guarantee NUL-termination. strncat() DOES guarantee NUL-termination. The padding may seem stupid and an inefficient but it makes a lot of sense in the intented contexts. Nobody ever claimed these are general purpose functions. Hence, don&#8217;t be shy to roll your own functions which make more sense in your context. Of course, make sure you specify them cleanly including corner-cases and test them. In C strings are not something abstract which is both an advantage and disadvantage.</p>
<p>strlcpy() can&#8217;t accept non-terminated data as source string and will also traverse the whole source string even if only a tiny part is copied. The latters makes it in efficient and an the former even insecure in many contexts.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: norbert</title>
		<link>http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html#comment-158</link>
		<dc:creator>norbert</dc:creator>
		<pubDate>Mon, 16 Feb 2009 05:39:56 +0000</pubDate>
		<guid isPermaLink="false">http://www.safercode.com/blog/?p=14#comment-158</guid>
		<description>&quot;Trivial snprintf() does miracles when you code safe string operations. For those in know - it does that for like ages now.&quot;

the printf familly of functions is everything but trivial. It is surely convienient, but the proposed abuse fall into the category of &#039;when all you have a hammer, everythings is a nail&#039;.

strncpy is usually enough

char buffer [MAX_SIZE + 1]
strncpy(buffer, input, MAX_SIZE)
buffer[MAX_SIZE = 0;

but more careful  is
if((size = strnlen(input, max_size)) &lt; max_size)
{
    memcpy(buffer, input, size);
    buffer[size] = 0;
}
else
{
   /* error processing */
}

For info:
#include 
#include 
#include 

int main(int argc, char**argv)
{
    char* source = argv[1];
    char buffer[200];
    int i;
    int size;

    if(argc &gt; 2 &amp;&amp; *argv[2] == &#039;s&#039;)
    {
        for(i = 0; i &lt; 100000000; i++)
        {
            snprintf(buffer, sizeof(buffer), &quot;%s&quot;, source);
            source[10] &#124;= i;
        }
    }
    else if(source)
    {
        for(i = 0; i &lt; 100000000; i++)
        {
            if((size = strnlen(source, 15)) &lt; 15)
            {
                memcpy(buffer, source, size);
                buffer[size] = 0;
                source[10] &#124;= i;
            }
        }
    }
    return 0;
}



$ time ./a.out &quot;foo&quot;

real    0m2.214s
user    0m2.210s
sys     0m0.000s
$ time ./a.out &quot;foo&quot; &quot;s&quot;

real    0m12.675s
user    0m12.593s
sys     0m0.000s

the printf version is 6 times!!! more expensive.

If that kind of performance waste is irrelevant to your program (and it could very well be), maybe you should not write it in C....</description>
		<content:encoded><![CDATA[<p>&#8220;Trivial snprintf() does miracles when you code safe string operations. For those in know &#8211; it does that for like ages now.&#8221;</p>
<p>the printf familly of functions is everything but trivial. It is surely convienient, but the proposed abuse fall into the category of &#8216;when all you have a hammer, everythings is a nail&#8217;.</p>
<p>strncpy is usually enough</p>
<p>char buffer [MAX_SIZE + 1]<br />
strncpy(buffer, input, MAX_SIZE)<br />
buffer[MAX_SIZE = 0;</p>
<p>but more careful  is<br />
if((size = strnlen(input, max_size)) &lt; max_size)<br />
{<br />
    memcpy(buffer, input, size);<br />
    buffer[size] = 0;<br />
}<br />
else<br />
{<br />
   /* error processing */<br />
}</p>
<p>For info:<br />
#include<br />
#include<br />
#include </p>
<p>int main(int argc, char**argv)<br />
{<br />
    char* source = argv[1];<br />
    char buffer[200];<br />
    int i;<br />
    int size;</p>
<p>    if(argc &gt; 2 &amp;&amp; *argv[2] == &#8217;s&#8217;)<br />
    {<br />
        for(i = 0; i &lt; 100000000; i++)<br />
        {<br />
            snprintf(buffer, sizeof(buffer), &#8220;%s&#8221;, source);<br />
            source[10] |= i;<br />
        }<br />
    }<br />
    else if(source)<br />
    {<br />
        for(i = 0; i &lt; 100000000; i++)<br />
        {<br />
            if((size = strnlen(source, 15)) &lt; 15)<br />
            {<br />
                memcpy(buffer, source, size);<br />
                buffer[size] = 0;<br />
                source[10] |= i;<br />
            }<br />
        }<br />
    }<br />
    return 0;<br />
}</p>
<p>$ time ./a.out &#8220;foo&#8221;</p>
<p>real    0m2.214s<br />
user    0m2.210s<br />
sys     0m0.000s<br />
$ time ./a.out &#8220;foo&#8221; &#8220;s&#8221;</p>
<p>real    0m12.675s<br />
user    0m12.593s<br />
sys     0m0.000s</p>
<p>the printf version is 6 times!!! more expensive.</p>
<p>If that kind of performance waste is irrelevant to your program (and it could very well be), maybe you should not write it in C&#8230;.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dummy00001</title>
		<link>http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html#comment-157</link>
		<dc:creator>Dummy00001</dc:creator>
		<pubDate>Sun, 15 Feb 2009 14:51:35 +0000</pubDate>
		<guid isPermaLink="false">http://www.safercode.com/blog/?p=14#comment-157</guid>
		<description>strlcpy() is non-standard and non-portable. Thanks to erratic *BSD folks, there are already at least two variants in the wild.

There is already better, standard, safe function serving the purpose perfectly - snprintf().

Tnstead of strcpy(a,b) - snprintf(a,sizeof(a),&quot;%s&quot;,b). Added bonus - snprintf( a, sizeof(a), &quot;%.*s&quot;, len_of_b, b ) - becomes critical when handling intermediate non-0 terminate strings.

Trivial snprintf() does miracles when you code safe string operations. For those in know - it does that for like ages now.</description>
		<content:encoded><![CDATA[<p>strlcpy() is non-standard and non-portable. Thanks to erratic *BSD folks, there are already at least two variants in the wild.</p>
<p>There is already better, standard, safe function serving the purpose perfectly &#8211; snprintf().</p>
<p>Tnstead of strcpy(a,b) &#8211; snprintf(a,sizeof(a),&#8221;%s&#8221;,b). Added bonus &#8211; snprintf( a, sizeof(a), &#8220;%.*s&#8221;, len_of_b, b ) &#8211; becomes critical when handling intermediate non-0 terminate strings.</p>
<p>Trivial snprintf() does miracles when you code safe string operations. For those in know &#8211; it does that for like ages now.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Shantanu Goel</title>
		<link>http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html#comment-156</link>
		<dc:creator>Shantanu Goel</dc:creator>
		<pubDate>Sun, 15 Feb 2009 09:34:45 +0000</pubDate>
		<guid isPermaLink="false">http://www.safercode.com/blog/?p=14#comment-156</guid>
		<description>Mark, you are correct. Thanks for pointing out the oversight on my part.</description>
		<content:encoded><![CDATA[<p>Mark, you are correct. Thanks for pointing out the oversight on my part.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mark</title>
		<link>http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html#comment-155</link>
		<dc:creator>Mark</dc:creator>
		<pubDate>Sun, 15 Feb 2009 04:36:36 +0000</pubDate>
		<guid isPermaLink="false">http://www.safercode.com/blog/?p=14#comment-155</guid>
		<description>I know this is an aside from your point but the line:

while(NULL != *src)

is incorrect because NULL is a special pointer value indicating the pointer has no value. You are comparing a pointer type with a char type - although it will often compile correctly if NULL is defined as 0. It won&#039;t compile if NULL is defined as (void *)0). You mean to use &#039;&#039; (often hash defined as nul) and is the character which terminates a C string.</description>
		<content:encoded><![CDATA[<p>I know this is an aside from your point but the line:</p>
<p>while(NULL != *src)</p>
<p>is incorrect because NULL is a special pointer value indicating the pointer has no value. You are comparing a pointer type with a char type &#8211; although it will often compile correctly if NULL is defined as 0. It won&#8217;t compile if NULL is defined as (void *)0). You mean to use &#8221; (often hash defined as nul) and is the character which terminates a C string.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Unsafe Functions In C And Their Safer Replacements: Strings Part II &#124; Safer Code - Secure Coding In C C++ And More..</title>
		<link>http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html#comment-15</link>
		<dc:creator>Unsafe Functions In C And Their Safer Replacements: Strings Part II &#124; Safer Code - Secure Coding In C C++ And More..</dc:creator>
		<pubDate>Tue, 02 Dec 2008 15:03:08 +0000</pubDate>
		<guid isPermaLink="false">http://www.safercode.com/blog/?p=14#comment-15</guid>
		<description>[...] In C And Their Safer Replacements: Strings Part II  Subscribe To Our Feed &#124; Follow Us On Twitter----Last time, we advised you to use ditch the unsafe functions like strcpy and strcat, and use their safer [...]</description>
		<content:encoded><![CDATA[<p>[...] In C And Their Safer Replacements: Strings Part II  Subscribe To Our Feed | Follow Us On Twitter&#8212;-Last time, we advised you to use ditch the unsafe functions like strcpy and strcat, and use their safer [...]</p>
]]></content:encoded>
	</item>
</channel>
</rss>
