Java: обнаружение управляющих символов, которые не подходят для JSON

Я заново изобретаю колесо и создаю свои собственные методы разбора JSON на Java.

Я пользуюсь (очень приятно!) документацией на json.org. Единственное, в чем я не уверен, так это в том, где написано "или управляющий символ".

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

Как мне правильно удалить управляющие символы в Java? Возможно, есть диапазон юникода?

введите здесь описание изображения


Редактировать: (обычно?) Отсутствующая часть головоломки

Мне сообщили, что существуют другие управляющие символы за пределами определенный диапазон 1 2< /a> это может вызвать проблемы в тегах <script>.

В частности, символы U+2028 и U+2029, разделители строк и абзацев, которые действуют как новые строки. Вставка новой строки в середину строкового литерала, скорее всего, вызовет синтаксическую ошибку (незавершенный строковый литерал). 3

Хотя я считаю, что это не представляет угрозы XSS, все же рекомендуется добавить дополнительные правила для использования в тегах <script>.

  • Просто будьте проще и кодируйте все символы, не предназначенные для печати ASCII, с помощью нотации \u. Эти персонажи необычны для начала. Если хотите, вы можете добавить в белый список, но я рекомендую подход с белым списком.
  • Если вы не знаете, не забывайте о </script (без учета регистра), что может привести к внедрению HTML-скрипта на вашу страницу с символами </script><script src=http://tinyurl.com/abcdef>. Ни один из этих символов по умолчанию не закодирован в JSON.

person 700 Software    schedule 18.05.2011    source источник
comment
Юникод есть Юникод. UTF-16 - это кодировка. Я думаю, что в Java есть тесты для группировок Unicode? См. документацию по классу символов для некоторых преамбул. мелочи и другие интересные функции.   -  person    schedule 19.05.2011
comment
Я имею в виду, что каждый символ в строке Java занимает два байта. Даже если данные представлены в формате ASCII, при преобразовании в строку получается два байта на строку.   -  person 700 Software    schedule 19.05.2011
comment
Для тех, кто не знает, Java работает с символами UTF-16. Ну да, вроде того. Тип String в Java хранит строковые данные внутри UTF-16, но Java прекрасно справляется с чтением и записью с использованием других кодировок (включая UTF-8 или Windows-1252 — обе широко используемые — и UTF-32). Возможно, стоит начать отсюда: joelonsoftware.com/articles/Unicode.html   -  person T.J. Crowder    schedule 19.05.2011
comment
Не беспокойтесь, я понимаю кодировку строк, даже если неправильно ее описываю.   -  person 700 Software    schedule 19.05.2011


Ответы (4)


Будет ли Character.isISOControl(.. .) делать? Между прочим, UTF-16 - это кодировка кодовых точек Unicode... Вы собираетесь работать на уровне байтов или на уровне символов/кодовых точек? Я рекомендую оставить сопоставление UTF-16 с символьными потоками с основными API-интерфейсами Java...

person Dilum Ranatunga    schedule 18.05.2011
comment
Я работаю на уровне персонажа. Байты преобразуются в строку перед началом синтаксического анализа JSON. - person 700 Software; 19.05.2011
comment
Я не знаю, правильно ли isISOControl. Я знаю, что так и будет, потому что это не обязательно должно быть строго правильным. :) - person 700 Software; 19.05.2011
comment
@George: Что ж, в документах говорится, что символ считается управляющим символом ISO, если его код находится в диапазоне от '\u0000' до '\u001F' или в диапазоне от '\u007F' до '\u009F', поскольку это соответствует определению, с которым я связан управляющего символа Unicode, я бы сказал, что @Dilum победил... :-) (Хотя я и педант, я, вероятно, хотел бы найти ссылку, говорящую, что эти два действительно были связаны, так что, если один меняется, мне не нужно беспокоиться о том, что они рассинхронизируются.) Но это, вероятно, педантизм. - person T.J. Crowder; 19.05.2011
comment
@T.J.: +1 тебе и jarnbjo. Принятие ответа Дилума, потому что это то, что я в итоге использовал. - person 700 Software; 19.05.2011
comment
@George: Вполне разумно! :-) - person T.J. Crowder; 19.05.2011

Даже если это не очень конкретно, я бы предположил, что они ссылаются на элемент управления " " категория символов из спецификации Unicode.

В Java вы можете проверить, является ли символ c управляющим символом Unicode, с помощью следующего выражения: Character.getType(c) == Character.CONTROL.

person jarnbjo    schedule 18.05.2011

Я считаю, что определение управляющего символа Unicode таково:

65 символов в диапазонах U+0000..U+001F и U+007F..U+009F.

Это их определение управляющего кода, но за приведенным выше следует предложение "Также известно как управляющие символы", так что...

person T.J. Crowder    schedule 18.05.2011

Я знаю, что вопрос был задан пару лет назад, но я все равно отвечаю, потому что принятый ответ неверен.

Character.isISOControl(int codePoint) 

выполняет следующую проверку:

(codePoint >= 0x00 && codePoint <= 0x1F) || (codePoint >= 0x7F && codePoint <= 0x9F);

Спецификация JSON определяет на странице https://tools.ietf.org/html/rfc7159:

  1. Струны

    Представление строк похоже на соглашения, используемые в языках программирования семейства C. Строка начинается и заканчивается кавычками. Все символы Unicode могут быть заключены в кавычки, за исключением символов, которые должны быть экранированы: кавычки, перевернутая косая черта и управляющие символы (от U+0000 до U+001F).

Character.isISOControl(int codePoint) 

пометит все символы, которые необходимо экранировать (U+0000-U+001F), хотя также пометит символы, которые не нужно экранировать (U+007F-U+009F). Не требуется экранировать символы (U+007F-U+009F).

person toongeorges    schedule 08.07.2016