Подтвердить что ты не робот

Как я дезинфицирую пользовательский ввод для правильного кодирования содержимого, прежде чем я его сохраню?

У меня есть приложение, в котором пользователи вводят текст в формы.

Данные сохраняются в базе данных MySQL (сортировка: utf8_general_ci), а затем выводятся как XML (кодирование: UTF-8).

Проблема заключается в том, что люди склонны вырезать и вставлять свою информацию из других источников, например, документы Microsoft Word или PDF файлы, например.

Этот текст ввода часто содержит символы, которые являются неправильными для выходной кодировки, такие как "умные кавычки", которые поступают из документа в кодировка Windows-1252

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

Итак, как дезинфицировать вход?

Раньше я использовал некоторые довольно грубые методы, такие как "de-moronize" script, который состоит из длинный список операций поиска и замены.

Это лучший способ сделать это? Есть ли другой путь?

Можно ли просто установить атрибут accept-charset в форме и сделать браузер для меня?

Если да, то какие браузеры будут делать это и могут ли возникнуть какие-либо проблемы?

Также, как моя база данных принимает эти символы, которые являются зарезервированными/управляющими символами в UTF-8?

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

ТИА

4b9b3361

Ответ 1

Этот текст ввода часто содержит символы, которые являются неправильными для выходной кодировки, такие вещи, как "умные кавычки", которые поступают из документа в кодировке Windows-1252

"Умные кавычки" (байты 147 и 148 в cp1252) являются вполне допустимыми символами Unicode, U + 201C и U + 201D. Ваша заявка должна быть способна легко обрабатывать их; если нет, вы делаете что-то не так, и, скорее всего, все символы, отличные от ASCII, потерпят неудачу.

Независимо от того, пришли ли персонажи от кого-то, набрав их или вставляя их из Word, браузер должен отправлять символы в кодировке UTF-8 в ваше приложение, которые должны хранить в базе данных те же байты UTF-8.

Если браузер не отправляется в UTF-8, скорее всего, вы не можете установить кодировку HTML-страницы, содержащей форму. Это можно сделать, используя:

Content-Type: text/html;charset=utf-8

HTTP-заголовок и/или:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

в <head> .

Можно ли просто установить атрибут accept-charset в форме и сделать браузер для меня?

Нет, accept-charset в основном бесполезен благодаря IE, который неправильно понимает, что это означает "попробуйте использовать эту кодировку, если тот, который на странице не может кодировать символы, которые мы хотим", вместо "всегда используйте эту кодировку". Это означает, что если вы используете accept-charset, вы можете получить смесь кодировок, представленных сразу, без возможности выяснить, что именно. Ницца!

Как моя база данных принимает эти символы, которые являются зарезервированными/управляющими символами в UTF-8?

В MySQL UTF-8 - это просто сортировка, используемая для сравнения и упорядочения. Он по-прежнему хранит данные в виде байтов, и их не волнует, если они не являются допустимыми последовательностями UTF-8.

В любом случае рекомендуется декодировать и проверять входящие последовательности UTF-8 в вашем приложении, поскольку "короткие последовательности", недействительные в современном Unicode, могут скрыть "< который по-прежнему будет распознаваться старыми браузерами (по крайней мере, IE6 до SP2, Opera 7).

ETA:

Итак, я ввел строку, содержащую байт 146

Нет, вы ввели символ Unicode U + 201B. Браузер имеет дело с символами Unicode, а не с байтами, вплоть до момента, когда он должен отправить сериализованную форму на сервер. Затем он решает, как превратить символы в байты, и если страница обрабатывается как UTF-8, она всегда будет выбирать UTF-8.

(Если это не UTF-8, браузеры, как правило, обманывают нестандартным образом: для всех символов, которые не могут вписываться в кодировку, они будут кодировать их к символам HTML-символов, например '& # 8217;. Это неправильно, потому что теперь вы не можете отличить между экранированным браузером & и реальным, введенным пользователем символом &, и это коварно неправильно, потому что если вы затем эхом ссылаетесь как неэкранированный HTML, он выглядит как будто вы все правильно поняли, что на самом деле вы просто сделали большую старую дыру в безопасности.)

Он попал в базу данных как 146

Действительно, '\ x92 байт, а не'\xC2\x92, '\ xE2\x80\x99 или' & # 146;?

это получилось, когда я выпустил XML (кодированный UTF-8), как 146. Никаких жалоб в браузере

Тогда он не появился как один 146-байтовый. Браузер будет жаловаться, если в файле XML будет указано "\ x92". (Не HTML файл, в котором недопустимые последовательности UTF-8 выходят в виде символа пропавшего символа.)

Я подозреваю, что он выходит как '& # 146; символьная ссылка, которая хорошо сформирована (хотя символ U + 0092 является частью набора управления C1, поэтому не будет отображаться как что-либо полезное). Если это то, что происходит, ваша страница формы не подбирается как UTF-8 в конце концов, и вы страдаете от проблемы с браузером-автоматическим экранированием, описанной выше.

Ответ 2

Вы можете попробовать модуль Perl Encode. Он поддерживает преобразование между несколькими наборами символов, включая UTF-8 couse. Я только что проверил мою установку Perl, а также поддерживал "cp1252", что является просто еще одним именем для Windows-1252 в соответствии с Википедией. Вы можете проверить свою собственную установку следующим лайнером:

perl -MEncode -e 'print map {"$_\n"} Encode->encodings(":all");'

Ответ 3

"Можно ли просто установить атрибут accept-charset в форме и сделать браузер для меня?"

Только если вы готовы доверять "браузеру", который может быть подходящим в некоторых приложениях, но в целом он оставляет вас открытым для озорства (или, что еще хуже).

(Также см. предупреждения bobince об IE...)

Иэйн