<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx</link><description>I created this bug a couple of weeks ago for a conference I spoke at to illustrate how so few lines of code could be so buggy. Where's the bug here? char dest[50], src[100]; int x, y; if (x=1) { strcpy(dest,src); dest[50] = '\0'; } return y; Solution:</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx#451672</link><pubDate>Mon, 15 Aug 2005 09:13:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:451672</guid><dc:creator>who</dc:creator><description>dest[50] doesn't exist? :-)&lt;br&gt;</description></item><item><title>re: Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx#451674</link><pubDate>Mon, 15 Aug 2005 09:24:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:451674</guid><dc:creator>Ceboz</dc:creator><description>I'm a little rusty but...&lt;br&gt;&lt;br&gt;src is unitialized (and if the memory allocator doesn't initialise memory to 0's then strcpy may not work correctly).&lt;br&gt;&lt;br&gt;We should not be copying from a char[100] to a char[50] if we don't know what the input is. (i.e. the null terminator (assuming there is one) could be after the 50th char in the src array.&lt;br&gt;x and y are not initialized before use. This is usually bad practice?&lt;br&gt;&lt;br&gt;if (x=1) is usually a programming error - depending on whether assignment (rather than straight equality) is required. In this case, it looks wrong in context.</description></item><item><title>re: Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx#451685</link><pubDate>Mon, 15 Aug 2005 10:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:451685</guid><dc:creator>Ryan Russell</dc:creator><description>Well, the point is bug density, right?&lt;br&gt;&lt;br&gt;char dest[50], src[100];&lt;br&gt;int x, y;//should probably be more specifc about what kind of int we want&lt;br&gt;&lt;br&gt;if (x=1)//assignment, you probably meant comparison.  If you meant comparison, x is uninitialized.&lt;br&gt;{&lt;br&gt;   strcpy(dest,src);//could overflow.  We don't see src filled in here, so it contains random stuff, unless that was just left out of the example.&lt;br&gt;   dest[50] = '\0';//the last array slot is dest[49]&lt;br&gt;}&lt;br&gt;&lt;br&gt;return y;//And what is y supposed to be?  It's uninitialzied&lt;br&gt;</description></item><item><title>re: Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx#451693</link><pubDate>Mon, 15 Aug 2005 10:35:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:451693</guid><dc:creator>Ceboz</dc:creator><description>Another one for you... &lt;br&gt;Assuming that X != 1 when running the above snippet and a modification is made to say &amp;quot;if (x==1)&amp;quot; as per the above comments. &lt;br&gt;Let's say X is expliticitly initialized to 0 as part of a code change, then dest is not initialized (the strcpy doesn't happen when x != 0). Any code after the if{} using dest as a null terminated string may access memory outside of the char[50] range.&lt;br&gt;&lt;br&gt;I recommend something like:&lt;br&gt;if(x==1)&lt;br&gt;{&lt;br&gt;  strcpy(dest,src);  &lt;br&gt;  dest[49] = '\0';&lt;br&gt;}&lt;br&gt;else&lt;br&gt;{&lt;br&gt;  // make sure dest[] is null terminated&lt;br&gt;  dest[0] = '\0';&lt;br&gt;}&lt;br&gt;&lt;br&gt;Any thoughts?</description></item><item><title>re: Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx#451735</link><pubDate>Mon, 15 Aug 2005 15:28:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:451735</guid><dc:creator>Radu Grigore</dc:creator><description>Is there anything right with this code? :p (except the syntax)</description></item><item><title>re: Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx#451793</link><pubDate>Mon, 15 Aug 2005 19:23:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:451793</guid><dc:creator>Dan Piton</dc:creator><description>This is a bit nonsensical, but I'll bite.&lt;br&gt;&lt;br&gt;char dest[50], src[100]; //1a&lt;br&gt;int x, y; //1b&lt;br&gt;&lt;br&gt;if (x=1) //2&lt;br&gt;{&lt;br&gt;   strcpy(dest,src); //3&lt;br&gt;   dest[50] = '\0'; //4&lt;br&gt;}&lt;br&gt;&lt;br&gt;return y; //5&lt;br&gt;&lt;br&gt;1a) Nothing is initialized.  One would think dest should be as long as src.  Perhaps hand &amp;quot;dest&amp;quot; to a ZeroMemory call.  &lt;br&gt;&lt;br&gt;1b) Again, nothing is initialzied and the names are weak.&lt;br&gt;&lt;br&gt;2) Assignment is very likely wrong, how about &amp;quot;if( 1 == x )&amp;quot;?&lt;br&gt;&lt;br&gt;3) strcpy isn't evil but it's close, perhaps consider using strncpy.  If strcpy required, perhaps make &amp;quot;src[49] = NULL;&amp;quot;&lt;br&gt;&lt;br&gt;4) &amp;quot;dest[50] = '\0';&amp;quot; is corrupting memory one character beyond the end of the array.&lt;br&gt;&lt;br&gt;5) &amp;quot;y&amp;quot; is returned never having been initialized at all. &lt;br&gt;&lt;br&gt;Additional comments:&lt;br&gt; - Even if initialized, the value y should probably change somewhere to make the retval mean something.&lt;br&gt; - If &amp;quot;src&amp;quot; is actually passed in to us, I'd like seen an &amp;quot;ASSERT( src )&amp;quot; and/or &amp;quot;IsBadReadPtr( src, 100 )&amp;quot;.&lt;br&gt; - dest is allocated on the stack, can be populated, and then goes unused before the stack unwinds</description></item><item><title>re: Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx#451796</link><pubDate>Mon, 15 Aug 2005 19:25:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:451796</guid><dc:creator>Dan Piton</dc:creator><description>This is a bit nonsensical, but I'll bite.&lt;br&gt;&lt;br&gt;char dest[50], src[100]; //1a&lt;br&gt;int x, y; //1b&lt;br&gt;&lt;br&gt;if (x=1) //2&lt;br&gt;{&lt;br&gt;   strcpy(dest,src); //3&lt;br&gt;   dest[50] = '\0'; //4&lt;br&gt;}&lt;br&gt;&lt;br&gt;return y; //5&lt;br&gt;&lt;br&gt;1a) Nothing is initialized.  One would think dest should be as long as src.  Perhaps hand &amp;quot;dest&amp;quot; to a ZeroMemory call.  &lt;br&gt;&lt;br&gt;1b) Again, nothing is initialzied and the names are weak.&lt;br&gt;&lt;br&gt;2) Assignment is very likely wrong, how about &amp;quot;if( 1 == x )&amp;quot;?&lt;br&gt;&lt;br&gt;3) strcpy isn't evil but it's close, perhaps consider using strncpy.  If strcpy required, perhaps make &amp;quot;src[49] = NULL;&amp;quot;&lt;br&gt;&lt;br&gt;4) &amp;quot;dest[50] = '\0';&amp;quot; is corrupting memory one character beyond the end of the array.&lt;br&gt;&lt;br&gt;5) &amp;quot;y&amp;quot; is returned never having been initialized at all. &lt;br&gt;&lt;br&gt;Additional comments:&lt;br&gt; - Even if initialized, the value y should probably change somewhere to make the retval mean something.&lt;br&gt; - If &amp;quot;src&amp;quot; is actually passed in to us, I'd like seen an &amp;quot;ASSERT( src )&amp;quot; and/or &amp;quot;IsBadReadPtr( src, 100 )&amp;quot;.&lt;br&gt; - dest is allocated on the stack, may be populated, and then goes unused before the stack unwinds&lt;br&gt; - Debugging Applications by John Robbins is the best programming book on the planet.</description></item><item><title>re: Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx#451912</link><pubDate>Tue, 16 Aug 2005 00:59:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:451912</guid><dc:creator>Bill</dc:creator><description>char dest[50], src[100];&lt;br&gt;int x, y;&lt;br&gt;&lt;br&gt;if (x=1)&lt;br&gt;{&lt;br&gt;   strcpy(dest,src); &lt;br&gt;   dest[50] = '\0';&lt;br&gt;}&lt;br&gt;&lt;br&gt;return y;&lt;br&gt;&lt;br&gt;There are three bugs here. I'm assuming that this is a local function, so initialization is already done by the compiler for me.&lt;br&gt;&lt;br&gt;1. x=1 is an assignment, while not wrong is probably not what you expected. Either way it falls through and executes the if.&lt;br&gt;&lt;br&gt;2. Copy of a 100 byte array to a 50 byte array is bound to cause problems. Can we say buffer overflow anyone??&lt;br&gt;&lt;br&gt;3. Setting dest[50] is a big no no. It hasn't been allocated by the compiler so it will corrupt the stack. This is my biggest gripe about the C/C++ language. Its non obvious to some poor smuck who is just learning the language that you have to ALWAYS count from 0, even when it hurts.&lt;br&gt;&lt;br&gt;4. Although technically not a bug, perhaps an unintended feature, the return of an unassigned y is always 0. Probably should have looked at the compiler warnings about using unassigned variables.&lt;br&gt;&lt;br&gt;</description></item><item><title>re: Spot the Bug - August 14, 2005</title><link>http://blogs.msdn.com/rsamona/archive/2005/08/14/451670.aspx#452902</link><pubDate>Thu, 18 Aug 2005 05:02:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:452902</guid><dc:creator>Bart</dc:creator><description>Hi folks,&lt;br&gt;&lt;br&gt;It's a good programming practice to change the order of comparison statements (despite the commutative properties). Let me give you the following example:&lt;br&gt;&lt;br&gt;if (x == 1)&lt;br&gt;&lt;br&gt;versus&lt;br&gt;&lt;br&gt;if (1 == x)&lt;br&gt;&lt;br&gt;The latter one maybe isn't easier to read, but it's safer against mistakes. Assume you forget one = symbol, leading to:&lt;br&gt;&lt;br&gt;if (x = 1)&lt;br&gt;&lt;br&gt;versus&lt;br&gt;&lt;br&gt;if (1 = x)&lt;br&gt;&lt;br&gt;The latter one will be caught by the C/C++ compiler as an error: you can't assign a variable to a constant. The former one can possible generate a warning but it's legal syntax, so you can overlook the problem.&lt;br&gt;&lt;br&gt;Allow me to refer to a post on my blog (&lt;a rel="nofollow" target="_new" href="http://blogs.bartdesmet.net/bart/archive/2005/07/27/3172.aspx"&gt;http://blogs.bartdesmet.net/bart/archive/2005/07/27/3172.aspx&lt;/a&gt;) where I'm using this guideline in Win32 API programming.&lt;br&gt;&lt;br&gt;Kind regards,&lt;br&gt;&lt;br&gt;Bart De Smet</description></item></channel></rss>