Русский

Что делают преобразователи синтаксиса

JSON, YAML, XML, TOML и CSV не содержат одни и те же вещи. На этой странице точно указано, как отображается каждая фигура, какие преобразования выполняются с потерями и что инструмент отказывается делать.

Что он конвертирует

Девять направленных преобразований: JSON в YAML, YAML в JSON, JSON в XML, XML в JSON, JSON в от TOML, от TOML до JSON, от YAML до TOML, от TOML до YAML и от JSON до CSV. Каждый из них запускается на вкладке вашего браузера; ничего не загружается.

Внутреннее преобразование работает одинаково: исходный документ считывается в обычное значение JavaScript, и это значение записывается в целевом формате. От YAML до TOML не является особым случаем, это читатель YAML, за которым следует записывающий TOML. Вот почему приведенные ниже предостережения указаны для каждого формата, а не для каждой пары — предупреждение о дате и времени TOML применяется везде, где появляется TOML.

CSV доступен только для записи, и это сделано намеренно. Чтение CSV означает угадывание разделителя, диалекта кавычек, того, является ли первая строка заголовком, и типа каждой ячейки — четыре предположения, каждое из которых преобразователь незаметно ошибается. Это работа для инструмента, который просит.

XML: атрибуты, массивы и выбранные нами правила.

XML не имеет канонического отображения JSON, поэтому пришлось выбрать соглашения. Они видны на экране всякий раз, когда XML является одним из двух форматов, и это именно они.

Атрибуты становятся ключами объекта с префиксом @. <user id="7"><name>Ada</name></user> читается как {"user":{"@id":"7","name":"Ada"}}. Префикс — это то, что предотвращает объединение атрибута и дочернего элемента с тем же именем в один ключ — <user id="7"><id>other</id></user> сохраняет оба.

Текст внутри элемента, который также имеет атрибуты или дочерние элементы, находится под ключом #text. Элемент, не содержащий ничего, кроме текста, сворачивается в этот текст. Раздел CDATA находится под #cdata, поэтому его содержимое явно представляет собой данные, а не разметку.

Повторяющиеся одноуровневые элементы становятся массивом. Имя элемента, которое появляется один раз, не становится массивом — XML не дает синтаксическому анализатору возможности отличить «список с одним элементом» от «одного значения», и никакой преобразователь не может придумать эту информацию. Если вам нужна стабильная форма, это аргумент в пользу схемы, а не более умного преобразователя.

Префиксы пространства имен сохраняются дословно: <ns:item> — это ключ ns:item, а xmlns:ns — это атрибут @xmlns:ns. Ничего не разрешается, не перезаписывается и не удаляется, поскольку разрешение префикса удаляет текст, который фактически содержался в документе.

Самозакрывающийся тег читается как пустая строка. Объявление XML, инструкции по обработке и комментарии удаляются. В противном случае инструмент пишет свое собственное объявление, а не DOCTYPE.

Написание XML, ключа, который не является допустимым именем элемента XML (один с пробелом, другой, начинающийся с цифры, третий, начинающийся с букв xml), отклоняется по имени, а не переписывается автоматически. Тихо переименованный элемент создает документ, который ничем не проверяется.

Внешние объекты отклоняются, а не просто отключаются

Документ XML может объявлять объекты в DOCTYPE. Парсер, расширяющий их, — это уязвимость XXE: объект, объявленный SYSTEM «file:///etc/passwd», читает локальный файл, объект, указывающий на URL, делает запрос, которым управляет злоумышленник, а цепочка внутренних объектов представляет собой отказ в обслуживании «миллиард смеха», который превращает несколько сотен байт в гигабайты.

Этот конвертер не настраивает синтаксический анализатор так, чтобы он был осторожен с DOCTYPE. Он отклоняет любой документ, содержащий его, прежде чем парсеру будет передан один байт, без возможности отключить отказ. Это делает гарантию свойством нашего кода, а не настройкой по умолчанию зависимости — и разница имеет значение, поскольку значения по умолчанию меняются между версиями, а наш собственный отказ покрывается тестами, которые передают ему каждую стандартную полезную нагрузку XXE и утверждают, что ничего не было получено и ничего не было расширено.

Практическая цена: документ с DOCTYPE не будет преобразован здесь, даже если он безвреден. Удалите DOCTYPE, если контент принадлежит вам.

TOML datetime не имеет эквивалента больше нигде

TOML 1.0 имеет четыре временных типа, а JSON, YAML и XML не имеют ни одного: смещение даты и времени (1979-05-27T07:32:00Z), локальная дата-время (1979-05-27T07:32:00, без зоны, намеренно), местная дата (1979-05-27) и местное время (07:32:00).

Каждый из них становится строкой RFC 3339 точно так, как он был записан, и преобразование сообщает вам, с какими значениями оно это сделало и к какому из четырех типов относится каждое из них. Альтернатива — выдача одного момента UTC для всех четырех — переместит местное время в зону, которую документ явно отказался указать, что является неправильным ответом, а не ответом с потерями.

Обратное преобразование создает строки в кавычках, а не дату и время. Таким образом, переход от TOML к JSON к TOML туда и обратно меняет типы этих значений. Невозможно обойти эту проблему без изобретения соглашения, которое должен был бы использовать принимающий инструмент, а изобрести его молча было бы еще хуже.

TOML целые числа имеют знак 64-бит; Числа JSON представляют собой IEEE-754 двойные значения. Целое число после 2^53 - 1 становится строкой с путем, указанным в предупреждении, а не теряет последние цифры из-за округления, которое вы не заметите.

TOML не имеет нуля. Нулевой ключ опускается в выводе и упоминается в предупреждении; значение null внутри массива становится пустой строкой, поскольку его удаление приведет к сдвигу каждого последующего индекса. Корнем документа TOML всегда является таблица, поэтому массив или простое значение в корне отклоняется с предложением, объясняющим, почему.

YAML: якоря, потоки и проблема Норвегии

YAML читается с использованием ограниченной схемы, которая может создавать только строки, числа, логические значения, значения NULL, списки и карты. Теги, создающие произвольные объекты — !!js/function, !!python/object/apply, !!binary — отклоняются, и в этом вся причина существования ограничения: загрузчик, который их учитывает, является конструктором произвольных объектов, носящим одежду конфигурационного файла.

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

Поток нескольких документов, разделенных ---, становится массивом документов, и об этом говорит преобразование. Ни один другой формат в этом инструменте не имеет потока, поэтому массив — единственное честное сопоставление.

YAML запрещает повторное использование ключа сопоставления, и каждый анализатор обрабатывает его по-своему. Этот инструмент сохраняет последнее значение (используется правило JSON.parse) и сообщает вам, что это произошло, с указанием позиции повтора. Молча выбросить документ было бы еще хуже; молча выбрать значение, не сказав об этом, было бы еще хуже.

Проблема Норвегии: в YAML 1.1 скаляры без кавычек y, да, on, no, off и код страны NO преобразуются в логические значения, и именно так список кодов стран превращается в список значений true и false. Этот инструмент читает YAML 1.2, где только true и false являются логическими значениями, поэтому NO остается строкой NO. Когда он записывает YAML, он цитирует каждую строку, которую синтаксический анализатор 1.1 может неправильно прочитать — «НЕТ», «да», «включено», «1.0», «0755», «2001-12-14» — поэтому выходные данные можно безопасно передать инструменту, который не перешел в 1.2. Это стоит нескольких символов кавычек и дает корректность.

Строки, похожие на числа, сохраняют кавычки по той же причине: «0755» остается строкой, а не становится 755, а «1.0» остается строкой, а не становится 1.

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

От JSON до CSV: выравнивание и апостроф, останавливающий формулу.

Массив становится строками, по одной записи на элемент. Объект, единственное свойство которого содержит массив, использует этот массив в качестве строк, потому что {"users": [ ... ]} в подавляющем большинстве случаев представляет собой таблицу с меткой, и преобразование громко заявляет, что оно это сделало. Любой другой объект представляет собой одну строку. Голая строка, число или ноль не принимаются: для прямоугольника нужны записи.

Вложенные объекты и массивы преобразуются в имена столбцов, разделенные точками, с точкой как для ключей объекта, так и для индексов массива: address.city, tags.0, tags.1. Один разделитель, одно правило. Ключ, который уже содержит точку, делает имя столбца неоднозначным из-за вложенного пути; инструмент предупреждает, а не изобретает схему выхода, которую не поймет ни одна электронная таблица.

Ключи объединяются в каждой строке в порядке их появления. Строка, в которой отсутствует поле, получает пустую ячейку, а не смещенный столбец, и преобразование предупреждает, что строки были неровными. Пустой объект или пустой массив становится одной пустой ячейкой на своем пути, а не исчезает.

Кавычки следуют за RFC 4180: поле, содержащее разделитель, двойную кавычку, CR или LF, заключено в двойные кавычки, а встроенная кавычка записывается дважды. Записи разделяются CRLF. Поля с начальными или конечными пробелами также заключаются в кавычки, поскольку в противном случае электронные таблицы автоматически обрезают их. Юникод передается без изменений, а для электронных таблиц, которым требуется чтение UTF-8, может быть добавлена ​​отметка порядка байтов.

Формула инъекции – это то, что кусается. Ячейка, начинающаяся с =, +, -, @, табуляции или возврата каретки, выполняется как формула в Excel, LibreOffice Calc и Google Sheets в момент открытия файла. =cmd|'/ccalc'!A1 — это демонстрация, которую все цитируют; =IMPORTXML(...) — тот, который незаметно отправляет лист куда-то. Конвертер, записывающий такую ​​строку дословно, превратил ваши данные в чужое выполнение кода в файл, который выглядит инертным.

Таким образом, текстовая ячейка, начинающаяся с одного из этих символов, имеет префикс апострофа, который во всех основных таблицах читается как «это текст» и не отображается в ячейке. Числа остаются в покое: числовое значение -5 — это число, а не формула. Сообщается о количестве экранированных ячеек, и экранирование можно отключить — в этом случае инструмент прямо говорит, что вы только что отключили.

CSV не может отличить пустую строку от нулевой. Обе становятся пустой ячейкой, и при преобразовании учитываются нули, чтобы вы знали, что это произошло.

Ограничения и что происходит, когда вы их достигаете

Каждый формат имеет ограничение на количество символов, которое применяется еще до загрузки анализатора: 8 миллионов для JSON, 4 миллионов для XML и для источника CSV, 2 миллионов для YAML и TOML. Кроме того, инструмент отказывается указывать точное число, а не превращается в неотвечающую вкладку, которая теряет то, что вы вставили.

Вывод CSV дополнительно ограничен строками 100,000 и столбцами 2,000, поскольку глубоко вложенный массив сглаживается до одного столбца на элемент, и несколько мегабайт JSON могут превратиться в таблицу, которую никакая электронная таблица не откроет.

Пустой ввод и ввод только с пробелами сообщается как пустой, а не преобразуется в значение NULL или пустой документ. О недопустимом синтаксисе сообщается строкой и столбцом во всех четырех читаемых форматах.

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

Что происходит с тем, что вы вставляете

  • Каждое преобразование, хеширование, декодирование и различие выполняются на вкладке вашего браузера. Никакие входные данные не загружаются, не регистрируются и не сохраняются на сервере, поскольку после загрузки страницы сервер не задействован.
  • Хэши берутся из собственной реализации Web Crypto в браузере, а UUID — из криптографически безопасного генератора случайных чисел. Ни один из них не предполагает сетевой вызов.
  • Ничего из того, что вы вводите, не записывается в локальное хранилище или файл cookie. Перезагрузка страницы удаляет ее; закрытие вкладки отменяет ее.
  • Аналитика в масштабе всего сайта выполняется только на настроенном каноническом рабочем хосте и описана в Политике конфиденциальности; локальные и предварительные хосты отказываются от этого. Вставленные значения, токены, URL-адреса и содержимое файлов исключаются из собственных аналитических событий ToolAcre. Реклама отключена в текущей конфигурации.
  • Тем не менее: ключ JWT или API — это действующие учетные данные. Безопасная привычка — никогда не вставлять его на веб-страницу, которую вы не писали, какими бы заслуживающими доверия ни были его утверждения, включая эту.

Вопросы

Почему мой документ XML выходит из строя с сообщением «объявляет DOCTYPE»?

Потому что он содержит объявление типа документа, и этот преобразователь отклоняет каждое из них, вместо того, чтобы доверять настройке синтаксического анализатора для безопасной обработки сущностей. Удалите DOCTYPE, если контент принадлежит вам. Нет возможности это разрешить.

Почему моя дата-время TOML вернулась в виде строки в кавычках?

Потому что JSON, YAML и XML не имеют типа даты. Дата и время были преобразованы в текст RFC 3339, в котором оно было записано, который представляет собой строку в любом другом формате. Таким образом, обратное преобразование создает строку, и инструмент предупреждает вас в тот момент, когда это происходит, вместо того, чтобы позволить вам узнать об этом позже.

Почему одна из моих ячеек CSV начинается с апострофа?

Потому что его текст начинается с =, +, -, @, табуляции или возврата каретки, а электронная таблица выполняет такую ​​ячейку как формулу при открытии файла. Апостроф отмечает ячейку как текст; оно не является частью значения после чтения ячейки. Вы можете отключить экранирование, и инструмент сообщит вам, что это означает.

Почему один повторяющийся элемент XML не является массивом?

Потому что XML не позволяет отличить список из одного значения от одного. Оба написаны одинаково. Предположение в любом направлении в половине случаев будет неправильным, поэтому инструмент сообщает то, что есть на самом деле.

Могу ли я здесь преобразовать CSV обратно в JSON?

Нет. Для правильного чтения CSV необходимо выбрать разделитель, диалект кавычек, является ли первая строка заголовком и тип для каждой ячейки. Преобразователь, который угадывает все четыре, незаметно ошибается, а это худший способ ошибиться. Используйте инструмент CSV, который запрашивает.

Почему «НЕТ» не преобразуется в ложь?

Потому что это поведение принадлежит YAML 1.1, а этот инструмент читает YAML 1.2, где только true и false являются логическими значениями. Поведение 1.1 является причиной того, что код страны Норвегии является шуткой в ​​управлении конфигурацией. Когда инструмент записывает YAML, он заключает такие строки в кавычки, поэтому ни один нижестоящий парсер 1.1 не может их неправильно прочитать.

Ограничения

  • CSV записан, никогда не читается. По выбору здесь нет преобразования CSV в JSON.
  • Комментарии теряются во всех направлениях, во всех форматах, где они есть.
  • Дата-время TOML становится строкой в ​​любом другом формате, поэтому циклический обход TOML меняет эти типы. Пути без потерь не существует.
  • Документ XML, содержащий DOCTYPE, категорически отвергается, в том числе безобидный, и отказ не может быть отключен.
  • Одиночный повторяющийся элемент XML невозможно отличить от неповторяющегося, поэтому от XML до JSON до XML не всегда возвращается исходная форма.
  • XML смешанный контент — текст, чередующийся с дочерними элементами, — теряет позицию текста относительно дочерних элементов и не может проходить туда и обратно.
  • Значения XML являются строками, если не включен вывод типа, поскольку XML не объявляет типы; при включенном выводе «0755» и «NO» могут быть неправильно истолкованы.
  • TOML не имеет значения NULL: ключи NULL удаляются из вывода TOML, а значения NULL внутри массивов становятся пустыми строками.
  • Корнем документа TOML должна быть таблица, поэтому массив или скаляр JSON вообще не может быть преобразован в TOML.
  • Числа JSON представляют собой IEEE-754 двойные значения. Целые числа после 2^53 преобразуются в строки, а не округляются без уведомления, что изменяет их тип.
  • CSV не может отличить пустую строку от нулевой; оба записываются как пустая ячейка.
  • При выравнивании CSV используется точка как для ключей объекта, так и для индексов массива, поэтому ключ, который уже содержит точку, создает неоднозначное имя столбца, о котором предупреждается, но не экранирует его.
  • YAML привязки и псевдонимы разрешаются, а не сохраняются; выходные данные не имеют привязок, а рекурсивный псевдоним отклоняется, поскольку ни один целевой формат не может выразить цикл.
  • Ввод ограничен для каждого формата — 8 миллионов символов для JSON, 4 миллионов для XML, 2 миллионов для YAML и TOML — а документы слишком большого размера отклоняются, а не обрабатываются медленно.
  • Ничто здесь не соответствует схеме. Документ может быть преобразован без ошибок, но при этом не соответствовать своему назначению.