Files
upload-platform/HISTORY/2026-09-05-gemini-review-qa.md
T

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-дефектами. Исправления кода в рамках этой записи не
выполнялись.