diff --git a/docs/1c-configuration-spec.md b/docs/1c-configuration-spec.md index aee9250f..5fc36301 100644 --- a/docs/1c-configuration-spec.md +++ b/docs/1c-configuration-spec.md @@ -475,7 +475,7 @@ ClassId — фиксированные идентификаторы классо | Файл | Описание | |------|----------| -| `ParentConfigurations.bin` | Информация о родительских конфигурациях (поставки) | +| `ParentConfigurations.bin` | Состояние поддержки: конфигурации поставщика + пообъектные правила. Формат: [1c-support-state-spec.md](1c-support-state-spec.md) | | `MobileClientSignature.bin` | Подпись мобильного клиента | --- diff --git a/docs/1c-specs-index.md b/docs/1c-specs-index.md index fb1f8769..8418688b 100644 --- a/docs/1c-specs-index.md +++ b/docs/1c-specs-index.md @@ -11,6 +11,7 @@ | `Configuration.xml` | Свойства и состав конфигурации | [1c-configuration-spec.md § 2](1c-configuration-spec.md#2-configurationxml--корневой-файл-конфигурации) | | `ConfigDumpInfo.xml` | Версии объектов (служебный) | [1c-configuration-spec.md § 3](1c-configuration-spec.md#3-configdumpinfoxml--служебный-файл-выгрузки) | | `Ext/` | Модули, интерфейс, начальная страница | [1c-configuration-spec.md § 4](1c-configuration-spec.md#4-ext--корневой-каталог-конфигурации) | +| `Ext/ParentConfigurations.bin` | Состояние поддержки (конфигурации поставщика, пообъектные правила) | [1c-support-state-spec.md](1c-support-state-spec.md) | | `Languages/` | Языки конфигурации | [1c-configuration-spec.md § 5](1c-configuration-spec.md#5-языки-languages) | --- diff --git a/docs/1c-support-state-spec.md b/docs/1c-support-state-spec.md new file mode 100644 index 00000000..16afdd0f --- /dev/null +++ b/docs/1c-support-state-spec.md @@ -0,0 +1,170 @@ +# Состояние поддержки конфигурации 1С — `Ext/ParentConfigurations.bin` + +Спецификация формата файла `Ext/ParentConfigurations.bin` из XML-выгрузки конфигурации 1С (`DumpConfigToFiles`). Файл хранит **состояние поддержки** конфигурации: глобальную «возможность изменения», список конфигураций поставщика и пообъектные правила поддержки (на замке / редактируется с сохранением поддержки / снят с поддержки). + +Это единственный исходник состояния поддержки в выгрузке: ни `Configuration.xml`, ни `ConfigDumpInfo.xml`, ни файлы объектов его не содержат. Знание формата нужно, чтобы статически (без запуска конфигуратора и без ИБ) определить, разрешено ли редактировать конкретный объект конфигурации поставщика. + +> Формат восстановлен реверс-инжинирингом на размеченных выгрузках (одиночная поддержка и образец с несколькими поставщиками), а не из документации 1С. Значения, помеченные **наблюдаемые**, подтверждены на конкретных объектах; помеченные **(не до конца разобрано)** — требуют дополнительных образцов. + +--- + +## 1. Где лежит и когда есть + +``` +/ + Ext/ + ParentConfigurations.bin # состояние поддержки (если конфигурация на поддержке) +``` + +| Состояние | Файл | +|-----------|------| +| Конфигурация **на поддержке** | присутствует, размер от сотен КБ до единиц МБ (запись на каждый объект конфигурации поставщика) | +| Поддержка **снята полностью** | присутствует, но усечён до ~16 байт (пустой контейнер) | +| Своя конфигурация (без поставщика) | файла нет | + +Грубый признак «это конфигурация поставщика» берётся независимо — из `Configuration.xml`: непустой `` + ``. + +--- + +## 2. Кодировка и общий вид + +- Кодировка: **UTF-8 с BOM** (`EF BB BF`). Несмотря на расширение `.bin`, содержимое — текст. +- Формат: 1С-овский фигурноскобочный контейнер `{ ... }`, элементы через запятую, строки в двойных кавычках (внутренняя кавычка удваивается: `"Фирма ""1С"""`). Ровно одна пара `{ }` на весь файл — вложенности нет. + +``` +{ 6, G, K, + <блок поставщика 1> + 0,0 + <блок поставщика 2> + 0,0 + ... + <блок поставщика K> } +``` + +- `6` — маркер формата. +- `G` — глобальная «возможность изменения» (§ 3). +- `K` — число конфигураций поставщика на поддержке (§ 5). При одиночной поддержке `K = 1`. +- Между блоками поставщиков — разделитель из двух токенов `0,0` (после последнего блока его нет). + +Каждый **блок поставщика**: + +``` +guidA, X, guidПоставщика, "версия", "вендор", "имя", count, + f1,f2,,, ← записи объектов, count штук + f1,f2,,, + ... +``` + +**Ключевая особенность: флаги `f1,f2` стоят ПЕРЕД своим uuid**, а не после. Это легко перепутать при наивном regex `uuid,uuid,int,int`. + +Парсер, разбирающий весь файл по этой грамматике, потребляет 100% токенов на образце с `K = 7` (458107 токенов, остатка нет) — грамматика подтверждена. + +--- + +## 3. Глобальная «возможность изменения» (`G`) + +Токен #2 контейнера (сразу после маркера формата `6`): + +- `G = 0` — изменение конфигурации поставщика **включено**; смотреть пообъектные правила `f1` (§ 4). +- `G = 1` — изменение **запрещено целиком**. Вся конфигурация read-only независимо от пообъектных правил. В этом режиме `f1` наблюдается равным `1` у всех объектов (значение неинформативно). + +> В блоке поставщика есть токен `X` (сразу после `guidA`), во всех образцах **равный `G`** (оба `1` при выключенной возможности, оба `0` при включённой). Отделить `X` от `G` по имеющимся образцам нельзя — для проверки достаточно трактовать `G`. **(не до конца разобрано)** + +--- + +## 4. Блок поставщика и пообъектные правила + +Поля заголовка блока: + +| Поле | Значение | +|------|----------| +| `guidA` | GUID блока, меняется от выгрузки к выгрузке (идентификатор снимка) | +| `X` | флаг, наблюдается равным `G` (§ 3) | +| `guidПоставщика` | стабильный GUID конфигурации поставщика | +| `"версия"` | версия конфигурации поставщика | +| `"вендор"` | поставщик | +| `"имя"` | имя конфигурации поставщика | +| `count` | число записей объектов далее | + +Каждая запись объекта: `f1, f2, , `. + +- `uuidLocal` — uuid объекта в **текущей** конфигурации (совпадает с `uuid="…"` на корневом элементе файла объекта). +- `uuidVendor` — uuid объекта в конфигурации **поставщика**. При одиночной поддержке обычно `uuidLocal == uuidVendor`; могут различаться. +- Первая запись блока — корень конфигурации; при одиночной поддержке записывается одним uuid (без пары `uuidVendor`). +- Присутствуют записи и на под-элементы (реквизиты, табличные части, формы и т.п.), поэтому записей кратно больше, чем объектов верхнего уровня. + +### Правило поддержки `f1` (при `G = 0`) + +| `f1` | Правило 1С | Редактирование | +|------|------------|----------------| +| `0` | объект поставщика **не редактируется** (на замке) | запрещено | +| `1` | объект поставщика **редактируется с сохранением поддержки** | разрешено | +| `2` | объект **снят с поддержки** / не включён в поддержку данного поставщика | разрешено | + +`f2` во всех образцах = `0` (вторичный флаг; кейса на его переключение не встретилось — **не до конца разобрано**). + +Проверка кодировки на диффе двух выгрузок одной конфигурации (включена возможность изменения → точечные правки правил): + +``` +…, 0→1 ,0, ← включение редактирования корня +…, 0→1 ,0, ← редактируется с сохранением поддержки +…, 0→2 ,0, ← снят с поддержки +``` + +Размер файла при смене правила не меняется (значения однозначные) — диффы точечные. + +--- + +## 5. Несколько поставщиков (`K > 1`) + +Когда конфигурация стоит на поддержке нескольких конфигураций поставщика, `K > 1`, и в контейнере идут `K` блоков подряд (через разделитель `0,0`). Каждый блок — свой поставщик со своим `count` и своим набором записей. + +Один и тот же объект (по `uuidLocal`) может присутствовать в нескольких блоках с **разными** правилами `f1` — у каждого поставщика своё правило относительно его поставки. В образце с `K = 7` таких объектов с расходящимися правилами — 166; наблюдаемые комбинации: + +| Комбинация `f1` у разных поставщиков | Сколько объектов | Трактовка | +|--------------------------------------|------------------|-----------| +| `0` и `1` | 127 | у одного на замке, у другого редактируется с сохранением поддержки | +| `1` и `2` | 38 | у одного редактируется, у другого снят / не включён | +| `0` и `2` | 1 | у одного на замке, у другого снят / не включён | + +Объект, отсутствующий в блоке поставщика, в поддержку этого поставщика не входит. + +### Эффективное правило при конфликте + +Для гейта «можно ли редактировать объект» важно: **редактирование любого из поставщиков, где `f1 = 0`, нарушит поддержку этого поставщика**. Поэтому консервативное (безопасное) правило свёртки: + +> объект считается **на замке**, если хотя бы у одного поставщика `f1 = 0`; иначе редактирование допустимо (`1`/`2` у всех включающих его поставщиков). + +Точная семантика «эффективного» правила, которую показывает сам конфигуратор при конфликте поставщиков, по имеющимся образцам не подтверждена — **(не до конца разобрано)**. Для guardrail рекомендуется консервативная свёртка выше. + +--- + +## 6. Алгоритм определения «можно ли редактировать объект» (статически) + +``` +1. Прочитать заголовок ParentConfigurations.bin в configSrc. + файла нет / размер ≈16 байт → поддержки нет → редактирование РАЗРЕШЕНО + G = 1 → возможность выключена → read-only ВСЁ (запрет) + G = 0 → перейти к шагу 2 +2. Путь редактируемого файла → корневой .xml объекта: + - сам файл объекта (Catalogs/X.xml, Documents/Y.xml) несёт uuid на корневом элементе; + - файл внутри каталога объекта (Catalogs/X/Ext/ObjectModule.bsl, + Catalogs/X/Forms/F/Ext/Form.xml) → подняться к корневому Catalogs/X.xml. + ConfigDumpInfo.xml для этого НЕ нужен (его может не быть в выгрузке/гите). +3. Собрать f1 по этому uuid (как uuidLocal) во ВСЕХ блоках поставщиков: + есть f1 = 0 хотя бы у одного → на замке → редактирование ЗАПРЕЩЕНО + иначе (только 1/2) → редактируется/снят → РАЗРЕШЕНО + uuid не найден ни в одном блоке → не на поддержке → РАЗРЕШЕНО +``` + +Под-элемент (отдельный реквизит, форма) отдельно проверять не обязательно: его XML нельзя отредактировать, не затронув файл объекта, поэтому достаточно правила верхнего объекта. + +--- + +## 7. Связанные форматы + +| Файл | Спецификация | +|------|--------------| +| `Configuration.xml` (Vendor, Version) | [1c-configuration-spec.md § 2](1c-configuration-spec.md#2-configurationxml--корневой-файл-конфигурации) | +| `Ext/` (где лежит .bin) | [1c-configuration-spec.md § 4.5](1c-configuration-spec.md#45-бинарные-файлы) | +| Расширения как альтернатива правке поставщика | [1c-extension-spec.md](1c-extension-spec.md) |