Моя программа Perl принимает некоторый текст из файла диска в качестве ввода, обертывает его в некоторый XML, а затем выводит его в STDOUT. Вход номинально UTF-8, но иногда вставляется старая. Мне нужно дезинфицировать вывод таким образом, чтобы не было выбрано ни одного недопустимого октета UTF-8, в противном случае потребитель вниз (Sphinx) взорвется.
По крайней мере, я хотел бы знать, недействительны ли данные, поэтому я могу избежать его передачи; В идеале я мог удалить только оскорбительные байты. Тем не менее, включение всех фатализмов, которые я могу найти, не приводит меня туда с perl 5.12 (FWIW, use v5.12; use warnings qw( FATAL utf8 );
).
У меня возникают проблемы с последовательностью "\xFE\xBF\xBE"
. Если я создаю файл, содержащий только эти три байта (perl -e 'print "\xEF\xBF\xBE"' > bad.txt
), пытаясь прочитать файл с ошибками :encoding(UTF-8)
в режиме :encoding(UTF-8)
с utf8 "\xFFFE" does not map to Unicode
, но только под 5.14.0. 5.12.3 и более ранние - это прекрасное чтение и последующая запись этой последовательности. Я не уверен, откуда он получает \xFFFE
(незаконную обратную спецификацию), но, по крайней мере, жалоба совместима с Sphinx.
К сожалению, decode_utf8("\xEF\xBF\xBE", 1)
не вызывает ошибок в 5.12 или 5.14. Я бы предпочел метод обнаружения, который не требовал кодированного уровня ввода-вывода, поскольку это просто оставит меня с сообщением об ошибке и не будет дезинфицировать необработанные октеты.
Я уверен, что есть несколько последовательностей, которые мне нужно адресовать, но просто обработка этого была бы началом. Поэтому я задаю следующие вопросы: могу ли я надежно обнаружить данные проблем с perl до 5.14? Какая процедура подстановки обычно может дезинфицировать почти UTF-8 в строгие UTF-8?