Что нового в 6.16.0
pypdf — «чистая» Python-библиотека для работы с PDF-файлами: объединяет, разрезает, извлекает текст и страницы, управляет аннотациями и метаданными. Предыдущая версия 6.15.0 вышла 6 августа 2026. Спустя неделю, 13 августа, разработчики опубликовали 6.16.0 с двумя целевыми исправлениями.
Первое касается AppearanceStream — механизма задания внешнего вида аннотаций в формате PDF. До 6.16.0 библиотека корректно применяла поворот только для стандартных значений: 0°, 90°, 180° и 270°. Любой другой угол обрабатывался некорректно — внешний вид аннотации не совпадал с ожидаемым. Теперь поддерживается произвольный угол вращения.
Второе исправление относится к надёжности: метод insert_child объекта TreeObject получил обнаружение кольцевых ссылок. Если дерево объектов в PDF содержит петлю — узел ссылается на самого себя или на предка — метод теперь прерывает обход, вместо того чтобы уходить в бесконечный цикл. Исправление закрывает баг #3964, зафиксированный в трекере проекта.
Вращение аннотаций: почему это важно
Аннотации в PDF — это наложенные на страницу элементы: текстовые пометки, выделения, штампы, формы, подписи и другие объекты. Каждая аннотация может иметь собственный AppearanceStream — поток описания внешнего вида, который задаёт, как именно она должна выглядеть при рендеринге: размер, положение, шрифт, цвет и в том числе угол поворота.
Спецификация PDF допускает произвольный угол вращения аннотации через матрицу трансформации. На практике большинство аннотаций повёрнуты на стандартные значения: горизонтально (0°), вертикально (90° или 270°) или вверх ногами (180°). Однако в реальных документах встречаются и нестандартные углы — например, в технических чертежах с диагональными пометками, в юридических документах со штампами под углом или в формах, где поле подписи намеренно наклонено.
Когда pypdf применял AppearanceStream с нестандартным углом, трансформация рассчитывалась неверно: аннотация оказывалась не там и не так, как задумано. При программном создании PDF-документов с такими аннотациями итоговый файл отображался в просмотрщиках с видимыми артефактами. Теперь библиотека корректно вычисляет матрицу для произвольного угла — вывод соответствует ожидаемому положению.
i
AppearanceStream и рендеринг аннотацийAppearanceStream — это необязательный, но важный компонент аннотации в PDF. Если он задан, просмотрщик использует именно его для отображения, игнорируя собственный стиль по умолчанию. Библиотеки-генераторы PDF, такие как pypdf, должны корректно строить этот поток, иначе результат зависит от того, насколько снисходительно каждый просмотрщик трактует неверную матрицу.
Защита от циклических деревьев объектов
PDF-документ устроен как граф взаимосвязанных объектов: страницы, шрифты, изображения, аннотации, аутлайн-дерево (оглавление) и другие структуры связаны между собой ссылками. В корректном PDF эти связи образуют направленный граф без циклов. Но в повреждённом, намеренно собранном или некорректно экспортированном файле узлы могут ссылаться на самих себя или на своих предков — образуется кольцо.
Если программа обходит такую структуру без проверки посещённых узлов, она входит в бесконечный цикл: обход идёт по кругу, процесс не завершается, процессор загружается полностью. Именно такой сценарий описывал баг #3964 в трекере pypdf: метод TreeObject.insert_child, отвечающий за вставку нового узла в дерево объектов, не проверял, не попал ли он уже в эту ветку дерева.
В версии 6.16.0 метод получил проверку посещённых узлов: при обходе дерева библиотека запоминает пройденные элементы и прерывает операцию, если один из них встречается повторно. Это тот же класс защиты, что был добавлен ранее для других частей pypdf — в частности, для нитей-статей (article threads) в релизе 6.13.1. Паттерн повторяется, потому что PDF по природе формата допускает циклические ссылки в нескольких независимых структурах, и каждую из них нужно защищать отдельно.
!
Чем это отличается от CVE-2026-54651В июле 2026 был закрыт баг CVE-2026-54651 — тоже зависание в pypdf, но в другом месте: функция _add_articles_thread при слиянии файлов с круговыми нитями-статьями. Баг #3964 из 6.16.0 — самостоятельное исправление другого метода TreeObject.insert_child. У него нет присвоенного CVE, он не классифицирован как уязвимость безопасности: злоумышленнику потребовался бы PDF, принятый конкретно через insert_child, что менее распространено в типовых пайплайнах.
Контекст: pypdf в серверных пайплайнах
pypdf — одна из наиболее используемых Python-библиотек для работы с PDF. Она не требует сторонних зависимостей и работает на любой платформе, где есть Python. Это делает её популярным выбором для автоматизации: генераторы отчётов, онлайн-конвертеры, системы документооборота, пайплайны извлечения данных из PDF, чат-боты и агенты, обрабатывающие присланные документы.
Именно из-за широкого распространения история pypdf в 2026 году насыщена точечными патчами: несколько версий подряд закрывали варианты бесконечных циклов при обработке специально собранных файлов. Логика здесь одна: библиотека принимает входные данные из ненадёжных источников, и любой нераскрытый путь к зависанию — это потенциальный вектор отказа в обслуживании. Об этой серии подробнее написано в нашей статье о CVE-2026-54651.
Для серверных приложений, которые принимают PDF от пользователей, своевременные обновления pypdf важнее, чем для десктопных инструментов. Одна входящая «петля» в дереве объектов может занять рабочий процесс целиком. Библиотека с защитой от циклов завершит операцию с ошибкой вместо зависания — это предсказуемое поведение, с которым приложение может справиться. Подробнее о том, каких форматов файлов стоит опасаться на сервере: раздел безопасность файлов.
Функциональное изменение с вращением аннотаций актуально для другого класса задач — программной генерации PDF: отчёты, накладные, технические документы, формы. Если аннотации в выходных файлах отображались с заметными артефактами при нестандартных углах поворота, обновление решает проблему без необходимости ручной коррекции.
Что делать
- Обновите pypdf до версии 6.16.0:
pip install --upgrade pypdf. Проверить текущую версию: pip show pypdf.
- Если ваше приложение генерирует PDF с аннотациями под нестандартными углами, проверьте результат после обновления — рендеринг должен совпасть с ожидаемым положением аннотации.
- Если pypdf используется для обработки входящих PDF от пользователей, обновление снижает риск зависания на файлах с циклическими деревьями объектов. Тем не менее рекомендуется сохранять тайм-аут на операции обработки PDF и изолировать обработку в отдельном процессе с ограничением ресурсов.
- Проверьте транзитивные зависимости: pypdf часто подтягивается как зависимость других пакетов. Команда
pip list | grep pypdf покажет установленную версию во всём окружении; pip-audit — известные уязвимости.
Источники
Данные приведены на 15 августа 2026 по материалам официального репозитория pypdf на GitHub. Версия 6.16.0 опубликована 13 августа 2026. Номер бага #3964 указан по трекеру проекта.