{"id":126,"date":"2009-10-28T21:01:46","date_gmt":"2009-10-28T23:01:46","guid":{"rendered":"http:\/\/www.ragestorm.net\/blogs\/?p=126"},"modified":"2009-11-21T01:05:13","modified_gmt":"2009-11-21T03:05:13","slug":"integer-promotion-is-dangerous","status":"publish","type":"post","link":"https:\/\/www.ragestorm.net\/blogs\/?p=126","title":{"rendered":"Integer Promotion is Dodgey &#038; Dangerous"},"content":{"rendered":"<p>I know this subject and every time it surprises me again. Even if you know the rules of how it works and you read K&#038;R, it will still confuse you and you will end up being wrong in some cases. At least, that&#8217;s what happened to me. So I decided to mention the subject and to give two examples along.<\/p>\n<p>Integer promotions probably happen in your code so many times, and most of us are not even aware of that fact and don&#8217;t understand the way it works. To those of you who have no idea what integer promotion is, to make a long story short: &#8220;Objects of an integral type can be converted to another wider integral type (that is, a type that can represent a larger set of values). This widening type of conversion is called &#8220;integral promotion.&#8221;, cited by MSDN. Why? So calculation can be faster in some of the times, otherwise because of different types; so seamless conversions happen, etc. There are exact rules in the standard how it works and when, you should check it out on your own<\/p>\n<pre lang=\"c\">\r\nenum {foo_a = -1, foo_b} foo_t;\r\n\r\nunsigned int a = -1;\r\nprintf(\"%s\", a == foo_a ? \"true\" : \"false\");<\/pre>\n<p>Can you tell what it prints?<br \/>\nIt will print &#8220;true&#8221;. Nothing special right, just works as we expect?<br \/>\nCheck the next one out:<\/p>\n<pre lang=\"c\">\r\nunsigned char a = -1;\r\nprintf(\"%s\", a == foo_a ? \"true\" : \"false\");<\/pre>\n<p>And this time? This one will result in &#8220;false&#8221;. Only because the type of &#8216;a&#8217; is unsigned. Therefore it will be promoted to unsigned integer &#8211; 0x000000ff, and compare it to 0xffffffff, which will yield false, of course.<br \/>\nIf &#8216;a&#8217; were defined as signed, it would be ok, since the integer promotions would make sure to sign extend it.<\/p>\n<p>Another simple case:<\/p>\n<pre lang=\"c\">\r\nunsigned char a = 5, b = 200;\r\nunsigned int c = a * b;\r\nprintf(\"%d\", c);<\/pre>\n<p>Any idea what the result is? I would expect it to be (200*5) &#038; 0xff &#8211; aka the low byte of the result, since we multiply uchars here, and you? But then I would be wrong as well. The result is 1000, you know why? &#8230; Integer Promotions, ta da. It&#8217;s <i>not<\/i> like c = (unsigned char)(a * b); And there is what confusing sometimes.<br \/>\nLet&#8217;s see some Assembly then:<\/p>\n<pre lang=\"asm\">\r\nmovzx       eax,byte ptr [a]\r\nmovzx       ecx,byte ptr [b]\r\nimul        eax,ecx\r\nmov         dword ptr [c],eax<\/pre>\n<p>Nasty, the unsigned char variables are promoted to unsigned int. Then the multiplication happens in 32 bits operand size! And then the result is <i>not<\/i> being truncated, just like that, to unsigned char again.<\/p>\n<p>Why is it dangerous? I think the answer is obvious.. you trivially expect for one result when you read\/write the code, but in reality something different happens. Then you end up with a small piece of code that doesn&#8217;t do what you expect it to. And then you end up with some <i>integer overflow vulnerability<\/i> without slightly noticing. Ouch.<\/p>\n<p><b>Update: Thanks to Daniel I changed my erroneous (second) example to what I really had in mind when I wrote this post.<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I know this subject and every time it surprises me again. Even if you know the rules of how it works and you read K&#038;R, it will still confuse you and you will end up being wrong in some cases. At least, that&#8217;s what happened to me. So I decided to mention the subject and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":""},"categories":[5,12,19,17],"tags":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pbWKd-22","_links":{"self":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts\/126"}],"collection":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=126"}],"version-history":[{"count":10,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts\/126\/revisions"}],"predecessor-version":[{"id":175,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts\/126\/revisions\/175"}],"wp:attachment":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=126"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=126"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=126"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}