fix(utf8): закрыть lossy-границы конфигурации и API
This commit is contained in:
@@ -597,10 +597,12 @@ production-профилем, а не ищет подстроки. Проверя
|
||||
(`check_utf8ness_and_warn`), и отказ там — `-EINVAL`, то есть **незагруженный
|
||||
файл окружения** и юнит, который не стартует. `unichar_is_valid` отвергает
|
||||
суррогаты, `U+FDD0..U+FDEF` и все code points вида `*FFFE`/`*FFFF`, а сам
|
||||
`utf8_is_valid` — встроенный NUL и невалидный UTF-8.
|
||||
`utf8_is_valid` — встроенный NUL и невалидный UTF-8. Публичная документация
|
||||
EnvironmentFile дополнительно запрещает U+FEFF. Реализация v257.13 случайно
|
||||
пропускает его из-за маски; HY2XS следует документированному контракту.
|
||||
|
||||
`isEnvTransportable` в `lib/envFile.ts` повторяет ровно это множество и ничего
|
||||
сверх него. Управляющие символы формат несёт — внутри двойных кавычек перевод
|
||||
`isEnvTransportable` в `lib/envFile.ts` повторяет документированное множество.
|
||||
Управляющие символы формат несёт — внутри двойных кавычек перевод
|
||||
строки накапливается как обычный байт и переживает round-trip, — и запрещает их
|
||||
контракт учётных данных, а не транспорт. Приписывать формату чужие запреты
|
||||
нельзя: именно так проверка и пропустила noncharacters, о которых ничего не
|
||||
@@ -610,6 +612,13 @@ production-профилем, а не ищет подстроки. Проверя
|
||||
вправе их содержать, а `TextEncoder` молча заменит непарный суррогат на
|
||||
`U+FFFD` — то есть без проверки в файл уехал бы **другой** секрет, а не отказ.
|
||||
|
||||
Сам файл читается только как байты и декодируется через
|
||||
`TextDecoder("utf-8", { fatal: true, ignoreBOM: true })`. Обычный
|
||||
`Bun.file(...).text()` запрещён на этой границе: он заменяет повреждённые байты
|
||||
на U+FFFD. `ignoreBOM: true` сохраняет BOM как U+FEFF, чтобы тот не исчез до
|
||||
транспортной проверки. Исходный текст целиком проверяется **до** разбора ключей:
|
||||
запрещённый символ не может спрятаться в комментарии или неизвестной переменной.
|
||||
|
||||
### Непригодная конфигурация отвергается до первой мутации
|
||||
|
||||
`validateRuntimeEnvTransport` вызывается из `parseRuntimeEnv`, а не при записи
|
||||
@@ -681,6 +690,13 @@ production-профилем, а не ищет подстроки. Проверя
|
||||
`redact-config` и diagnostics-бандл используют **структурную** редакцию: YAML
|
||||
разбирается и обходится как дерево.
|
||||
|
||||
Diagnostics не копирует env/YAML и не перенаправляет сырой journal/systemctl
|
||||
сразу в staging. Сначала данные читаются или захватываются в память, проходят
|
||||
редакцию и лишь затем записываются с режимом `0600`. Некорректный UTF-8 в
|
||||
конфигурационном файле даёт безопасный маркер пропуска без исходных байтов.
|
||||
Вывод каждой внешней команды ограничен 8 МиБ на поток и при усечении явно
|
||||
помечается; архив создаётся сразу под `umask 077`.
|
||||
|
||||
Это не косметика. Построчное правило `auth:\s*(.*)` подставляло маркер в
|
||||
заголовок mapping'а и оставляло нетронутым вложенный
|
||||
`auth.http.url` с `access_token=<секрет>`, то есть бандл уносил machine token
|
||||
|
||||
Reference in New Issue
Block a user