{"id":80,"date":"2007-10-03T15:17:45","date_gmt":"2007-10-03T14:17:45","guid":{"rendered":"https:\/\/www.dont-panic.cc\/capi\/2007\/10\/03\/net-strings-are-not-always-immutable\/"},"modified":"2007-10-03T15:26:06","modified_gmt":"2007-10-03T14:26:06","slug":"net-strings-are-not-always-immutable","status":"publish","type":"post","link":"https:\/\/www.dont-panic.cc\/capi\/2007\/10\/03\/net-strings-are-not-always-immutable\/","title":{"rendered":".NET strings are not always immutable!"},"content":{"rendered":"<p><code>Strings<\/code> are immutable. If you want to modify a sequence of characters, use <code>StringBuilder<\/code>. At least, that&#8217;s whats officially said. But in the framework there is at least one method that does modify a string:<\/p>\n<p><code>TextRenderer.MeasureText()<\/code> with <code>ModifyString<\/code> and <code>EndEllipses<\/code>  will modify your string  to match the ellipsed text if ellipsing happens. You can look at this <a href=\"http:\/\/www.codeproject.com\/useritems\/NewPathCompactPath.asp\" aiotitle=\"VB# example on codeproject using TextRenderer.MeasureText() for trimming text\">VB# example on codeproject using <code>TextRenderer.MeasureText()<\/code> for trimming text<\/a> on how it is used.<\/p>\n<p>The string seems to be modified directly in native code by <code>DrawTextEx<\/code> from <code>user32.dll<\/code>. Additionally to the scary fact that strings are not immutable, the length of the string is not updated, regardless if the resulting string is shorter!<\/p>\n<p>For instance if you have a string &#8220;<code>aaaaaaa<\/code>&#8221; which will be truncated to &#8220;<code>aa...<\/code>&#8220;, the <code>Length<\/code> property will still return 7 for the shortened string.  The debugger shows that the string will in fact be &#8220;aa&#8230;\\0a&#8221; after the operation. So maybe it might be right that the string is still 7 characters long but most outputting functionality like <code>Console.Out.WriteLine()<\/code> gets confused sometimes and stops any further output to the debugger or console under certain conditions.<\/p>\n<p>A very quick investigation of the System.Drawing assembly using Lutz Roeder&#8217;s fabulous <a href=\"http:\/\/www.aisto.com\/roeder\/dotnet\">.NET Reflector<\/a> showed that at least there should be no memory corruption in case &#8220;<code>WW<\/code>&#8221; would get ellipsed to &#8220;<code>W...<\/code>&#8220;, as <code>DrawTextEx<\/code> takes the length of the buffer and should result only in &#8220;<code>W.<\/code>&#8220;.<\/p>\n<p>Summing up, I find the <em>corruption<\/em> of an immutable string <em>by an official Microsoft API<\/em> very troubling.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Strings are immutable. If you want to modify a sequence of characters, use StringBuilder. At least, that&#8217;s whats officially said. But in the framework there is at least one method that does modify a string: TextRenderer.MeasureText() with ModifyString and EndEllipses will modify your string to match the ellipsed text if ellipsing happens. You can look &hellip; <a href=\"https:\/\/www.dont-panic.cc\/capi\/2007\/10\/03\/net-strings-are-not-always-immutable\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;.NET strings are not always immutable!&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,4,7],"tags":[23,45,138,225,227],"class_list":["post-80","post","type-post","status-publish","format-standard","hentry","category-computer","category-development","category-security","tag-net","tag-bug","tag-c","tag-development","tag-security"],"_links":{"self":[{"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/posts\/80","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/comments?post=80"}],"version-history":[{"count":0,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/posts\/80\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/media?parent=80"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/categories?post=80"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dont-panic.cc\/capi\/wp-json\/wp\/v2\/tags?post=80"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}