{"id":107241,"date":"2022-10-03T07:00:00","date_gmt":"2022-10-03T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=107241"},"modified":"2022-10-03T09:16:48","modified_gmt":"2022-10-03T16:16:48","slug":"20221003-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20221003-00\/?p=107241\/","title":{"rendered":"Feel free to stop using IMultiLanguage2::DetectInputCodepage"},"content":{"rendered":"<p>A customer reported that they were observing some weird behavior when passing the text of an email message to <code>IMultiLanguage2::<wbr \/>DetectInputCodepage<\/code>. They were passing the <code>MLDETECTCP_HTML<\/code> flag, claiming that <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150223-00\/?p=44613\"> I recommended passing that flag<\/a>, but found that using that flag caused <code>DetectInputCodepage<\/code> to detect the wrong code page, whereas if they passed <code>MLDETECTCP_NONE<\/code>, the detection worked a little better. Not perfectly, but a little better.<\/p>\n<p>Okay, first of all, they appear to have read only the first half of the sentence where I explained when to pass the <code>MLDETECTCP_HTML<\/code> flag:<\/p>\n<blockquote class=\"q\"><p>One thing that may not be obvious is that the program passes the <code>MLDETECTCP_HTML<\/code> flag <span style=\"border: solid 1px gray;\">if the file extension is <code>.htm<\/code> or <code>.html<\/code><\/span>.<\/p><\/blockquote>\n<p>Somehow the customer though I was recommending that you always pass the <code>MLDETECTCP_HTML<\/code> flag. No, you pass that flag only if you are passing in HTML. That way, the detector will not consider text inside angle brackets as evidence that the contents are written in English. That text is part of the HTML tags and is not part of the message text.<\/p>\n<p>&#8220;The customer found that the <code>MLDETECTCP_NONE<\/code> flag works for them. We want to know if there are any risks of using that flag instead of the <code>MLDETECTCP_HTML<\/code> flag.&#8221;<\/p>\n<p>The risk is that you might be providing correct information to the <code>DetectInputCodepage<\/code> function and therefore allow it to perform as intended. I guess that&#8217;s a good risk.<\/p>\n<p>But really, feel free to stop using <code>IMultiLanguage2::<wbr \/>DetectInputCodepage<\/code>!<\/p>\n<p>Code page detection is never going to be reliable. The function has always been a guess. An educated guess based on available information but it&#8217;s still a guess. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bush_hid_the_facts\">Guesses can be wrong<\/a>.<\/p>\n<p>The customer wrote back, &#8220;For the attached message, <code>DetectInputCodepage<\/code> returns code page 1252 when passed <code>MLDETECTCP_NONE<\/code>, but when we use code page 1252 to convert the message to Unicode, the results are incorrect. If we explicitly convert with code page 28592, then the results are correct. Is there a workaround for this?&#8221;<\/p>\n<p>The workaround is to pass 28592 when the code page is 28592. You can get the code page from other metadata attached to the message, such as a <code>charset=<\/code> attribute in the <code>Content-Type<\/code>. If that metadata is missing, then you are going to be forced to guess, and the nature of guessing is the possibility that you might guess <i>wrong<\/i>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You should have been keeping your eye on the code page all along.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-107241","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>You should have been keeping your eye on the code page all along.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107241","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=107241"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107241\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=107241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=107241"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=107241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}