79 lines
5.5 KiB
Markdown
79 lines
5.5 KiB
Markdown
# Вопросы и ответы по ревью Gemini 3.8 Flash — 2026-09-05
|
|
|
|
## Контекст
|
|
|
|
После критического разбора ревью Gemini 3.8 Flash были заданы уточняющие
|
|
вопросы по версии исходников, дублированию API, семантике `File.name`, legacy
|
|
XSS, `build.mjs`, ZIP-фильтрации и приоритетам исправлений.
|
|
|
|
## Зафиксированные ответы
|
|
|
|
### Версия кода и номера строк
|
|
|
|
Ревью выполнялось по исходникам `upload-platform`; `dist/` отдельно не
|
|
исследовался. Номера строк в первой сводке были смещены из-за объединения
|
|
отчётов субагента. Фактические участки находятся в текущих исходниках
|
|
`on_files_change.js` и `list_zip_files.js`.
|
|
|
|
### `init_upload_table.js`
|
|
|
|
Буквального совпадения интерфейса с `initFilePicker` нет: один entry point
|
|
принимает готовые DOM-узлы, другой создаёт DOM внутри `mount`. Однако внутренняя
|
|
логика жизненного цикла таблицы параллельна: состояние `nodes/fileKeys/busy`,
|
|
удаление узлов, делегирование кликов и похожий API. Файл не входит в граф сборки
|
|
`build.mjs`, поэтому это legacy-альтернатива, создающая риск рассинхронизации.
|
|
|
|
### `File.name` и логический путь
|
|
|
|
`flattenFiles()` возвращает `name`, `path` и `file` раздельно, но при `rebaseTree`
|
|
вложенный browser `File` получает полный путь в `file.name`. При прямом
|
|
`FormData.append('files', file)` сервер получает filename с разделителями пути.
|
|
Это может конфликтовать с серверными `basename`/`secure_filename` и нарушает
|
|
обычный контракт browser `File`, где `name` является базовым именем. При явной
|
|
передаче третьего аргумента `FormData.append('files', file, path)` проблема не
|
|
возникает.
|
|
|
|
### XSS в `set_status.js`
|
|
|
|
Замечание относится только к legacy-файлу. `set_status.js` не входит в активный
|
|
граф сборки и не используется боевым рендерером. В активном `render.js` значения
|
|
статуса экранируются через `esc()`. Реальная уязвимость в текущем активном
|
|
рендеринге не подтверждена; пункт относится к гигиене мёртвого кода.
|
|
|
|
### `build.mjs`
|
|
|
|
Для top-level `await` необработанная ошибка сборки сама приводит Node.js к
|
|
завершению с ненулевым кодом. Явные `try/catch` и `process.exit(1)` технически
|
|
избыточны. Реальное возможное улучшение этого пункта — определить поведение
|
|
каталога `dist/` перед сборкой, например его предварительную очистку.
|
|
|
|
### Проверка фильтра `fflate`
|
|
|
|
Проверка исходника `fflate` подтвердила, что `filter` вызывается после чтения
|
|
метаданных ZIP entry, но до копирования или декомпрессии данных. Если фильтр
|
|
возвращает `false`, `inflateSync` для этой записи не вызывается и буфер для
|
|
распакованных данных не создаётся. Поэтому добавление проверки расширения в
|
|
`filter` является корректным способом не распаковывать тяжёлые неразрешённые
|
|
entries.
|
|
|
|
### Приоритет до прода
|
|
|
|
Согласован обязательный приоритет:
|
|
|
|
1. **№2:** отбрасывать неразрешённые расширения внутри ZIP `filter` до
|
|
декомпрессии, чтобы снизить риск OOM и лишнего расхода бюджета.
|
|
2. **№1:** сбрасывать `elements.fileInputEl.value`, чтобы повторный выбор того
|
|
же файла после удаления снова генерировал `change`.
|
|
3. **№5:** объединять корневые папки с одинаковыми путями, чтобы избежать
|
|
дублирующихся деревьев при последовательном выборе.
|
|
|
|
Пункты `File.name`, `onError`, fallback-конфигурация, legacy-код и очистка
|
|
служебных каталогов отнесены ко второй очереди.
|
|
|
|
## Итог
|
|
|
|
Уточнение подтвердило, что главным техническим finding является ZIP-фильтрация
|
|
до декомпрессии. Пункты про `set_status.js` и явный `process.exit(1)` не являются
|
|
активными production-дефектами. Исправления кода в рамках этой записи не
|
|
выполнялись.
|