Skip to content

Аудит зависимостей: закрыть RustSec и обновить совместимые версии - #3

Merged
alexstep merged 9 commits into
mainfrom
cursor/deps-audit-1d01
Oct 21, 2026
Merged

alexstep merged 9 commits into
mainfrom
cursor/deps-audit-1d01

Conversation

@alexstep

@alexstep alexstep commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

Исправлено

Находка Исправление Тест
Zip-бомба: maxBytes не ограничивал распаковку docx, pptx, epub, odt, pkpass и xlsx/ods через calamine Сумма распакованных записей не больше maxBytes (при безлимитном вводе остаётся потолок 64 МиБ). Больше 4096 записей тоже отклоняется. Маленький архив: лимит 8 КиБ, запись 16 КиБ. docx, pptx, epub, odt, xlsx и ods кидают Input exceeds max size. До правки такая распаковка проходила.
Вечный цикл в acquire_working_set Если вес одного файла больше рабочего набора, сразу Input exceeds working set. Семафор при этом не держится. Буфер 2 МиБ при setMaxWorkingSetMB(1) кидает ошибку, а не ждёт.
Усечение u64 → usize на 32-bit Длина файла сравнивается как u64. file_len_exceeds отклоняет u32::MAX + 10 при лимите 100. Усечённое до u32 значение было бы меньше лимита.
Релиз ставил зависимости без lockfile Все bun install в release.yml, включая FreeBSD, с --frozen-lockfile. Проверено локально: bun install --frozen-lockfile.
Фиктивный NODE_AUTH_TOKEN в publish actions/setup-node@v7 в job публикации. v7 не подставляет XXXXX-…, если секрет не задан. Остальные setup-node@v6 не ставят registry-url. Поведение action, отдельного теста в репозитории нет.
Имя пакета в bun.lock @calendar/doc-extract → @alexstep/doc-extract. bun install --frozen-lockfile проходит.
cargo audit не в CI Шаг в job lint. Предупреждение ttf-parser unmaintained сборку не роняет.
Отравленный RwLock Чтение через into_inner, процесс не паникует. Юнит-тест травит замок и читает значение.

Оставлено

  • mmap PDF. Mmap::map в src/formats/pdf.rs оставлен. Варианты: читать файл в Vec после проверки размера (убирает unsafe, пиковое потребление как у буфера, публичный текст не меняется); оставить mmap и документировать, что усечение файла во время разбора — неопределённое поведение POSIX. Выбор за автором, в этот PR mmap не трогался повторно.
  • Список хостов для URL. extractText('https://…') по-прежнему качает любой http(s) и следует редиректам. Варианты: опция allowUrls: false; опция allowedHosts с ручной проверкой каждого редиректа; по умолчанию запретить приватные адреса. Любой из них — новое публичное поведение, в код не добавлялся.
  • setMaxConcurrent(0) по-прежнему ничего не делает, как написано в README. Вариант: трактовать 0 как снятие пользовательского лимита до встроенного потолка 512, по аналогии с setMaxFilesizeMB(0). Это сломает текущий контракт.
  • @napi-rs/cli 3.8+. С 3.8 napi build создаёт временный каталог в родителе крейта и здесь падает с EACCES. Оставлен 3.7.4.
  • Zig 0.14.1, actions/checkout v7, actions/cache v6. Мажоры без прогона musl-кросса и матрицы.
  • base64 0.23 и thiserror 2. Уязвимостей нет.
  • ttf-parser 0.25.1 unmaintained (RUSTSEC-2026-0192) через lopdf 0.42. Замены внутри pdf-extract нет.
  • CI не собирает FreeBSD, WASI, i686 и armv7. Эти цели остаются в release.yml.
  • EPUB и PPTX останавливают текст после 10 МиБ. Это прежний продуктовый предел. Отдельная запись и сумма распакованных байт режутся maxBytes.

Зависимости

cargo audit после обновления уязвимостей не показывает. bun audit чистый. memmap2 поднят до 0.9.11 (RUSTSEC-2026-0186) и остаётся, потому что PDF по-прежнему отображается в память.

Зависимость Было Стало Почему
zip 2.4.2 9.0.5 RUSTSEC-2026-0367/0368/0369
quick-xml 0.38.4 0.42.0 RUSTSEC-2026-0194 и 0195
pdf-extract / lopdf 0.7.12 / 0.34.0 0.12.1 / 0.42.0 RUSTSEC-2026-0187
calamine 0.31.0 0.37.0 Старый zip и quick-xml
html2text 0.13.6 0.17.4 Цикл на битом CSS, паники, стек
memmap2 0.9.10 0.9.11 RUSTSEC-2026-0186
napi, napi-derive, napi-build 3.9.0, 3.5.6, 2.3.2 3.14.2, 3.6.12, 2.6.0 Миноры
tokio, regex, serde_json, encoding_rs 1.52.3, 1.12.3, 1.0.150, 0.8.35 1.54.0, 1.13.1, 1.0.154, 0.8.42 Патч и минор
docx-rs, крейт epub 0.4.20, 2.1.5 удалены Не вызывались и держали старый zip
@emnapi/*, @napi-rs/wasm-runtime, @types/bun 1.10.0, 1.1.4, 1.3.14 1.11.3, 1.2.5, 1.4.3 Миноры
@napi-rs/cli 3.7.0 3.7.4 Патч. Линия 3.8+ не взята
cross-platform-actions/action v1.1.0 v1.6.0 Минор, FreeBSD 14.2 на месте
actions/setup-node (publish) v6 v7 Без фиктивного npm-токена

Проверки

cargo fmt, cargo clippy --all-targets -- -D warnings, cargo test (34), bun run build, bun test, node --test __tests__/formats.test.mjs (57).

Open in Web Open in Cursor 

cursoragent and others added 9 commits October 21, 2026 09:31
Поднять zip до 9, quick-xml до 0.42, pdf-extract до 0.12, calamine до 0.37
и html2text до 0.17. Неиспользуемые docx-rs и крейт epub удалены: они
удерживали старые копии zip и quick-xml.

Co-authored-by: kellas <alex.step.kellas@gmail.com>
@napi-rs/cli оставлен на линии 3.7.4: с 3.8 сборка создаёт временный
каталог рядом с корнем крейта и в этом окружении падает с EACCES.

Co-authored-by: kellas <alex.step.kellas@gmail.com>
Минорное обновление внутри v1. FreeBSD 14.2 в этой версии всё ещё поддерживается.

Co-authored-by: kellas <alex.step.kellas@gmail.com>
maxBytes теперь ограничивает суммарный распакованный размер zip, включая
xlsx и ods до вызова calamine. Слишком тяжёлый working set отклоняется сразу.
Длина файла сравнивается как u64. PDF читается в память, без mmap.
setMaxConcurrent(0) снимает пользовательский лимит до потолка 512, а
отравленный RwLock больше не роняет процесс.

Co-authored-by: kellas <alex.step.kellas@gmail.com>
allowUrls и allowedHosts не меняют поведение по умолчанию. Тесты проверяют
zip-бомбу docx/xlsx/ods, отказ рабочего набора и редирект на чужой хост.

Co-authored-by: kellas <alex.step.kellas@gmail.com>
Публикация использует actions/setup-node v7, чтобы не подставлять фиктивный
NODE_AUTH_TOKEN. Сборки ставят зависимости через bun install --frozen-lockfile.

Co-authored-by: kellas <alex.step.kellas@gmail.com>
В lockfile было @calendar/doc-extract, в package.json — @alexstep/doc-extract.

Co-authored-by: kellas <alex.step.kellas@gmail.com>
Отказ от mmap и список хостов меняют поведение и остаются на решение
автора. setMaxConcurrent(0) снова ничего не делает, как описано в README.

Co-authored-by: kellas <alex.step.kellas@gmail.com>
docx, pptx, epub, odt, xlsx и ods с лимитом 8 КиБ и записью на 16 КиБ
должны кидать ошибку размера. Раньше такая распаковка проходила.

Co-authored-by: kellas <alex.step.kellas@gmail.com>
@alexstep
alexstep marked this pull request as ready for review October 21, 2026 10:27
@alexstep
alexstep merged commit 0e1774c into main Oct 21, 2026
9 checks passed
@alexstep alexstep mentioned this pull request Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants