RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Small. Fast. Reliable.
Choose any three.
Недействительная политика UTF

1. Мусор

Относительно недействительного UTF SQLite следует за политикой Garbage-In, Garbage-Out (GIGO). Если вы вставляете недействительный UTF в базу данных SQLite, то при попытке запросить те данные, что вы возвращаете, не могут быть точно теми, что вы вставляете. Если вы вставляете мусор, то вы не можете жаловаться, что возвращаете мусор.

В целях этого обсуждения, "недействительный UTF" может означать любое из следующих обстоятельств:

  • Недействительные суррогатные пары в UTF-16.

  • Недействительные мультибайтные последовательности в UTF-8.

  • Использование большего количества байтов UTF-8, чем необходимо, чтобы представлять единственную кодовую точку. Пример: кодируя как двухбайтовая последовательность 0xc1, 0x01 вместо просто единственного байта 0x41.

  • Символы NUL (U+0000) включены в последовательности.

  • Недействительные последовательности комбинированных символов.

  • Последовательности байтов UTF-8 или UTF-16, которые кодируют числа, которые не являются определенными знаками Unicode.

1.1. Недействительный UTF никогда не будет вызывать ошибки памяти

Если вы вставляете недействительный UTF в базу данных SQLite, то SQLite не делает гарантий о том, какой текст вы могли бы возвратить. Но это обещает, что недействительный UTF никогда не будет вызывать ошибки памяти (выход за пределы множества, чтение или запись неинициализированной памяти и т.д.), по крайней мере для встроенной обработки SQLite. Другими словами, недействительный UTF не заставит SQLite терпеть крах.

Это обещание относится только к основным компонентам SQLite, не обеспеченным применением расширения, конечно. Если приложение добавляет новые определенные приложением функции SQL, виртуальные таблицы, последовательности сопоставления или другие расширения, а база данных содержит недействительный UTF, то недействительный UTF мог бы быть передан в те расширения. Если недействительный UTF заставляет одно из тех расширений терпеть крах, то это проблема с расширением, а не с SQLite.

2. Никакого осуществления правил формата текста

SQLite не пытается провести в жизнь форматирующие правила UTF. Можно вставить недействительный UTF в поле TEXT, и SQLite не будет жаловаться на это. Это хранит недействительный TEXT как может. SQLite видит свою роль в мире как система хранения, а не проверки текстового формата.

3. Максимальные усилия сохранить текст

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

Например, если вы вставляете некоторый UTF-16LE с недействительными суррогатами в столбец TEXT базы данных, у которой есть PRAGMA encoding=UTF16LE, тогда более поздний запрос колонки, используя sqlite3_column_text16(), вероятно, возвратит тот же самый точный недействительный UTF-16. Но если вы вставляете то же самое недействительное содержание UTF-16LE в БД с PRAGMA encoding=UTF8, содержание должно быть преобразовано в UTF8, когда это сохранено, что может вызвать необратимые изменения содержания. Или если вы вставляете то же самое недействительное содержание UTF-16LE в базу данных с PRAGMA encoding=UTF16LE, но читаете его используя sqlite3_column_text(), конвертация UTF16 в UTF8 должна произойти во время считывания, и это преобразование могло бы ввести необратимые изменения.

Или, предположите, что вы делаете все, используя UTF-8 (наиболее распространенный случай). Недействительный UTF-8 будет обычно проходить через базу данных без любого изменения в его последовательности байт. Однако, при попытке преобразовать недействительный UTF-8 функцией SQL вроде substr() или replace() или при попытке сделать проверку соответствия последовательности через оператор LIKE, вы могли бы получить неожиданные результаты.

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

4. Недействительный UTF в схеме базы данных

Если схема базы данных будет содержать имена (имена таблиц, столбцов, индексов и т.д), которые являются недействительным UTF, SQLite продолжит работать как обычно. С точки зрения SQLite, те имена это просто последовательности байт. SQLite не заботится, являются ли они действительным UTF или нет.

Производя сообщения об ошибках (используя, например, sqlite3_errmsg()), иногда SQLite будет включать части схемы базы данных в сообщение об ошибке. Если те вложенные элементы схемы недействительный UTF, то получающееся сообщение об ошибке могло бы также быть недействительным UTF. Точно так же вывод PRAGMA integrity_check и подобных запросов будет иногда включать названия элементов схемы. Если те имена элементов схемы будут недействительным UTF, то вывод команды также будет недействительным UTF.