Кратко

  • Файлы, соответствующие RFC 8610, охвачены новой грамматикой, но поддержка записи \u{hex} старыми процессорами не гарантирована (RFC 9682).
  • Отказ или неожиданное принятие сообщения сужают расследование, но не определяют виновный этап. Для этого нужно восстановить связь между исходной моделью, её преобразованиями и реально применённой проверкой.

Результат исполнения: что именно он опровергает

CDDL служит для описания структур CBOR и JSON; RFC 8610, раздел 4 рассматривает, в частности, автоматическую проверку данных. Рассмотрим способ работы, при котором из модели заранее получают валидатор — программу проверки сообщений. Это инженерное решение, а не обязательная архитектура, заданная CDDL.

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

Для CBOR разграничение закреплено в RFC 8949, разделе 1.2: well-formed означает соответствие синтаксической структуре, valid добавляет семантические ограничения CBOR, а expected — требования приложения. Синтаксически корректные данные не обязательно допустимы на следующих уровнях. Аналогично, способность декодировать сообщение не удостоверяет его соответствия прикладной схеме.

Практическая рекомендация — сохранять точные байты сообщения, источник диагностического результата и условия принятия решения. Само ожидание тоже требует основания: почему именно это сообщение должно быть принято или отклонено? Без независимого ответа расследование рискует объявить ошибкой корректное применение ограничения.

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

Потребитель: какую проверку он действительно применил

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

Нужны два отдельных свидетельства: что требуемый артефакт оказался в распоряжении приложения и что именно он определял рассматриваемую проверку. Даже подтверждённая загрузка не отвечает на вопрос, был ли соответствующий механизм задействован при обработке данного сообщения. Поэтому поиск следует вести по фактическому выполнению, а не по предполагаемому устройству приложения.

Обратный вывод также недопустим. Принятое сообщение не доказывает, что потребитель умеет читать новый синтаксис CDDL. В рассматриваемой архитектуре он может получать готовый валидатор и вообще не разбирать исходную модель. Способность инструмента разработки понимать фигурные скобки и способность приложения принимать соответствующие данные — разные свойства.

При сопоставлении значений необходимо сохранять не только содержимое, но и тип. RFC 8949, раздел 3.1 различает байтовые и текстовые строки; последние кодируются в UTF-8. Совпадение байтов содержимого не делает эти типы взаимозаменяемыми. Следовательно, проверять только видимый текст диагностического сообщения недостаточно: нужно установить, какие данные и какого типа дошли до валидатора.

Валидатор: откуда взялось его поведение

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

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

Для проверки происхождения полезно повторное построение при зафиксированных исходных данных, версиях и параметрах. Побайтовое совпадение результата укрепляет вывод о воспроизводимости именно этих условий, но не доказывает правильность модели или генератора. Различие требует объяснения; само по себе оно также не означает изменения семантики. Следует отдельно сравнивать состав артефакта и поведение существенных ограничений.

Рекомендуемый порядок локализации — находить первую подтверждённую точку расхождения при одинаковых входах и условиях. Если семантическое представление совпадает, а созданные из него проверки ведут себя по-разному в одинаковой среде, следует исследовать их построение. Если различие заметно уже в представлении модели, проверке подлежит более раннее преобразование. Обнаруженное отличие задаёт направление поиска; его причинную связь с решением потребителя ещё нужно подтвердить.

Разбор модели: что исправляет стандарт

На следующей границе требуется установить, какое представление вообще было передано компилятору. «Модель разобрана» без сохранённого результата и указания анализатора — слишком слабое свидетельство для объяснения последующего поведения. Оно не показывает, какие значения литералов, типы и ограничения были распознаны.

Нормативный ориентир здесь конкретен: приложение A RFC 9682 заменяет собранную ABNF приложения B RFC 8610, а не весь RFC 8610. Errata 6527 касается экранирования текстовых строк, 6278 — согласованности допустимых символов, 6526 — потерянных обратных косых черт. Errata 6543 учтена через семантическую обработку содержимого байтового литерала после синтаксического разбора, без предложенного разделения правил. Errata 6575 уточняет объяснение чисел в обозначениях тегов и простых значений (разделы 2, 3.2 и приложение B).

Добавленная запись \u{hex} задаёт скалярное значение Unicode шестнадцатерично; прежние формы \uXXXX и \uHHHH\uLLLL сохраняются. Использование нового синтаксиса не гарантирует принятия существующими реализациями (RFC 9682, раздел 2).

Отсюда аналитический вывод: успех синтаксического разбора нельзя повышать до свидетельства завершённой семантической обработки. Для расследования нужно видеть не только отсутствие ошибки, но и распознанное значение. Иначе утверждения «анализатор принял модель» и «компилятор получил предусмотренное ограничение» остаются несвязанными.

Сохранённое представление полезно сравнивать с исходной записью и нормативным смыслом независимо от последующего валидатора. Проверка только готового результата способна обнаружить расхождение, но не покажет, появилось ли оно при чтении литерала или позднее. Факт принятия файла старым инструментом также не устанавливает соответствия файла стандарту: прежняя терпимость реализации не является нормативным критерием.

Исходные байты: последняя проверка обратного пути

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

Раздел 2.4 RFC 5234 отделяет синтаксис ABNF от внешнего кодирования. Для самого CDDL RFC 8610, раздел 3.1 задаёт UTF-8 и указывает, что обработка не включает нормализацию Unicode. Практический вывод — не подменять сохранённый вход заново набранным, визуально похожим текстом. Преобразование исходника до анализатора, если оно предусмотрено, требует отдельного подтверждения.

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

При этом запись литерала относится к модели, а не обязательно к передаваемому сообщению. Из принятия CBOR нельзя восстановить, каким способом соответствующее значение было записано в CDDL. Поэтому наблюдаемая совместимость сообщений не подтверждает совместимость исходных моделей между инструментами.

Объяснение должно быть уже, чем первоначальное подозрение

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

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

RFC 9682, раздел 4 предупреждает о неодинаковой интерпретации моделей обновлёнными и необновлёнными инструментами и рекомендует обращаться с моделями столь же внимательно, как с исходным кодом. Это основание для проверки, но не свидетельство конкретной атаки.

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