воскресенье, 15 мая 2011 г.

unicodeFFFE... Microsoft рехнулась?

Это перевод unicodeFFFE... is Microsoft off its rocker? Автор: Майкл Каплан.

Это вопрос, который был открыт какое-то время.

Тогда в феврале (боже, я действительно писал в блог целый год?) я объяснил разницу между Big Endian и Little Endian Unicode. В январе я также говорил про Byte Order Mark.

Но этот пост не про это.

Этот пост - про Preferred Charset Label для web-страниц, которые кодируются в Big Endian Unicode (или 'Unicode (Big Endian)', как любит называть его Блокнот).

Это на самом деле unicodeFFFE.

"Но, Майкл, это не является допустимой кодовой точкой Unicode!" - плачут одни.

"Но, Майкл, это не то, как выглядит в памяти big endian BOM, если посмотреть на байты!" - плачут другие.

"Но, Майкл, это не то, как big endian BOM выглядит на Big Endian системах!" - плачет часть оставшихся людей.

"Майкл, Microsoft сошла с ума?" - вопрошают оставшиеся (они употребляют намного менее вежливый язык, но я нашёл письмо с самой вежливой формой и поэтому использую именно её).

И, верите вы или нет, вот некоторые баги, которые были сообщены нам людьми из разных команд за эти годы, которые не были счастливы из-за одной или нескольких вещей:
  1. Результаты MLang
  2. Encoding.BigEndianUnicode.WebName
  3. Preferred Charset Label в Internet Explorer
  4. Документация MSDN, которая говорит про unicodeFFFE
Вот несколько слов от людей из Microsoft...

"Byte-order mark для big-endian unicode - это FEFF, так что это должно называться UnicodeFEFF. Это выглядит разумно, но я боюсь что-то сломать, если буду это менять" - объясняет Shawn Steele, разработчик и владелец кодировок в Windows и .NET Framework.

"Я думаю, что это была ошибка в изначальных данных MLang, но нам приходится сохранять это по соображениям обратной совместимости" - объясняет разработчик, кто раньше работал над и владел MLang, а теперь глава разработки MUI.

"Да, это неправильное употребление термина, которое мы унаследовали от MLang. Слишком поздно менять это сейчас" - объясняет глава разработки NLS.

"Да, это было неверно в первой реализации. Но сейчас код приложений содержит эту константу, так что мы не можем её изменить" - объясняет архитектор Chris Lovett из команды SQL Server team.

Но правда в том, что оригинальное название из MLang вовсе не такое уж безумное. Вообще, Windows (да и Microsoft) живут в мире преимущественно Little Endian (даже когда Windows запускается на BE платформах вроде Alpha, всё равно при этом используется LE). И когда кто-то на little endian системе читает два байта как если бы они были одним WideChar (думая, что это кодовая точка UTF-16 LE), то они видят #$FFFE, что, конечно же, не является допустимой кодовой точкой Unicode. Вот почему так легко увидеть, что это big endian.

UTF-16 BOM - это всегда U+FEFF. Всегда. ВСЕГДА. Но это означает, что в памяти это будет (в байтах):
  • $ff $fe - little endian BOM на любой системе.
  • $fe $ff - big endian BOM на любой системе.
Это потому что big endian системы берут первый (старший, big) байт первым, а little endian системы первым берут второй байт. Что означает, что в памяти это будет (в словах):
  • $feff - little endian BOM на little endian системах.
  • $fffe - big endian BOM на little endian системах.
  • $fffe - little endian BOM на big endian системах.
  • $feff - big endian BOM на big endian системах.
Попробуйте это на любой вашей платформе, если вы мне не верите :-)

Семантика достаточно прозрачна и очевидна, просто плохо документирована, и, возможно, кто-то посчитает её глупым способом думать так про эти вещи. Название unicodeFFFE действует как несколько разумная (хотя и несколько платформенно-провинциальная) маркировка того, что все видят на почти 100% всех платформ Windows.

Как уже сказали другие люди, сейчас в любом случае поздно это менять...

This post brought to you by U+fffe, навечно зарезервированной кодовой точкой в Unicode, так что вся эта BOM идентификация сможет оставаться простым делом...

1 комментарий:

  1. Такое поведение исправлено в новых версиях Windows/MLang:
    В Windows XP MLang сообщает unicodeFFFE
    В Windows 7 MLang сообщает unicodeFEFF

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.