libarchive
libarchive — это свободная кроссплатформенная библиотека для чтения, записи и обработки потоковых архивов различных форматов. Она предоставляет единый программный интерфейс (API) для работы с архивами, сжатыми и несжатыми данными, поддерживая широкий спектр форматов, включая tar, cpio, zip, 7z, ISO 9660, ar, mtree, raw и другие. Библиотека написана на языке C и распространяется под лицензией BSD (New BSD License), что позволяет использовать её как в свободных, так и в проприетарных проектах. libarchive лежит в основе многих утилит командной строки, в частности, bsdtar и bsdcpio, которые являются альтернативами стандартным GNU-версиям.
История
Разработка libarchive была начата Тимом Кирби (Tim Kientzle) в 2003 году. Первоначальной целью было создание эффективной и безопасной замены стандартным утилитам архивации в операционной системе FreeBSD. Кирби стремился решить проблемы, присущие существующим решениям: слабую поддержку потоковой обработки, уязвимости к переполнению буфера и зависимость от внешних библиотек. Первая стабильная версия, libarchive 1.0, была выпущена в 2004 году.
В 2005 году libarchive была включена в состав базовой системы FreeBSD, заменив собой утилиты GNU tar и GNU cpio. Это решение было обусловлено модульностью библиотеки, её ориентацией на безопасность и поддержкой широкого спектра форматов. В последующие годы libarchive была портирована на другие операционные системы, включая Linux, macOS, Windows и Solaris. В 2010 году проект перешёл под эгиду сообщества FreeBSD, а его разработка стала вестись на платформе GitHub.
Ключевым этапом в развитии libarchive стало добавление поддержки формата 7z (через библиотеку LZMA SDK) и формата ZIP с шифрованием. В 2017 году была выпущена версия 3.3.0, в которой была реализована поддержка многотомных архивов и улучшена обработка метаданных. На 2025 год последней стабильной версией является 3.7.7 (выпущена в 2024 году), в которой исправлены уязвимости безопасности и добавлена поддержка новых алгоритмов сжатия, таких как Zstandard (zstd).
Архитектура и принцип работы
libarchive построена на модульной архитектуре, основанной на концепции «фильтров» и «форматов». Это позволяет библиотеке обрабатывать данные в несколько этапов:
- Чтение/запись базового потока: Библиотека работает с произвольным потоком данных (файл, сокет, память), а не с файловой системой напрямую. Это обеспечивает поддержку потоковой архивации.
- Фильтры сжатия: libarchive поддерживает цепочки фильтров, которые применяются к данным до или после их чтения/записи. Поддерживаются алгоритмы: gzip, bzip2, lzip, lzma, xz, compress, lz4, zstd и brotli. Фильтры могут быть вложенными (например, архив
tar.gzобрабатывается как фильтр gzip, применённый к формату tar). - Форматы архивов: Библиотека содержит модули для каждого поддерживаемого формата. Каждый модуль отвечает за разбор заголовков, извлечение записей (entries) и запись метаданных. Основные форматы:
- tar: POSIX.1-1988 (ustar), POSIX.1-2001 (pax), GNU tar extensions.
- cpio: SVR4, odc, hpbin.
- zip: PKZIP, Info-ZIP, с поддержкой шифрования (ZipCrypto, AES-256).
- 7z: 7-Zip (LZMA, LZMA2, PPMd, BZip2, Deflate).
- ISO 9660: образы CD/DVD (Rock Ridge, Joliet).
- ar: UNIX-архивы (ar, GNU ar).
- mtree: описание иерархии файлов.
- raw: неформатированные данные (например, для чтения сжатых файлов без архива).
- empty: пустой формат (для тестирования).
- API для работы с записями: Библиотека предоставляет набор функций для итерации по записям (entries) в архиве, получения их метаданных (имя, размер, права доступа, время модификации, владелец, символические ссылки) и чтения/записи данных.
Основные структуры данных
struct archive: основная структура, представляющая собой экземпляр библиотеки. Может быть открыта для чтения (archive_read) или записи (archive_write).struct archive_entry: структура, описывающая одну запись в архиве (файл, директорию, символическую ссылку, жёсткую ссылку, устройство). Содержит все метаданные, а также указатель на данные (при чтении) или буфер для записи.
Классификация и виды
libarchive можно классифицировать по нескольким признакам:
По назначению
- Библиотека для разработчиков: Основное назначение — предоставление API для встраивания в другие программы.
- Утилиты командной строки:
bsdtarиbsdcpio, которые являются обёртками над libarchive и предоставляют интерфейс, совместимый с GNU tar и cpio.
По поддерживаемым форматам
- Универсальная библиотека: Поддерживает более 20 форматов архивов и 10 алгоритмов сжатия.
- Специализированная: В отличие от многих других библиотек, libarchive не поддерживает форматы RAR (из-за закрытости спецификации) и некоторые проприетарные форматы.
По лицензии
- Свободная (BSD): Позволяет использовать в любых проектах, включая коммерческие, без обязательного раскрытия исходного кода.
Применение
libarchive широко используется в различных областях:
В операционных системах
- FreeBSD, NetBSD, OpenBSD: Входят в базовую систему, используются для создания и распаковки пакетов, установки обновлений, резервного копирования.
- Linux: Многие дистрибутивы (Debian, Ubuntu, Fedora, Arch Linux) используют
bsdtarв качестве альтернативы или дополнения к GNU tar. Например, в Arch Linuxbsdtarявляется стандартной утилитой для работы с пакетами. - macOS: Входит в состав Xcode и используется для работы с архивами в системных утилитах.
- Windows: Доступна в виде порта (например, через MSYS2, Cygwin) или встроена в некоторые программы.
В программном обеспечении
- Системы управления пакетами:
apt,dpkg,rpm,pacmanиспользуют libarchive для распаковки и упаковки пакетов. - Файловые менеджеры: Nautilus, Dolphin, Thunar могут использовать libarchive через бэкенды (например,
libarchive.soдля GNOME Files). - Архиваторы: PeaZip, 7-Zip (через плагин), WinRAR (ограниченно) могут использовать libarchive для чтения/записи форматов, которые не поддерживаются их собственными библиотеками.
- Веб-серверы и приложения: Nginx, Apache, Node.js (через модули) используют libarchive для распаковки загружаемых архивов.
- Инструменты резервного копирования:
duplicity,borg,resticмогут использовать libarchive для чтения/записи архивов. - Научные и инженерные приложения: В Python, Perl, Ruby, Rust существуют модули, обёртывающие libarchive, что позволяет использовать её в скриптах и приложениях.
В системах автоматизации и CI/CD
- Jenkins, GitLab CI, GitHub Actions: Используют libarchive для распаковки артефактов и зависимостей.
- Docker: В некоторых версиях используется libarchive для распаковки образов контейнеров.
Примеры использования
Чтение архива на C
```c
include <archive.h>
include <archive_entry.h>
include <stdio.h>
int main() { struct archive a; struct archive_entry entry; int r;
a = archive_read_new(); archive_read_support_filter_all(a); // Поддержка всех фильтров сжатия archive_read_support_format_all(a); // Поддержка всех форматов архивов
r = archive_read_open_filename(a, "archive.tar.gz", 10240); if (r != ARCHIVE_OK) { fprintf(stderr, "Ошибка открытия: %s\n", archive_error_string(a)); return 1; }
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { printf("Файл: %s\n", archive_entry_pathname(entry)); printf("Размер: %lld байт\n", (long long)archive_entry_size(entry)); // ... чтение данных с помощью archive_read_data() }
r = archive_read_free(a); if (r != ARCHIVE_OK) { fprintf(stderr, "Ошибка закрытия: %s\n", archive_error_string(a)); return 1; } return 0; } ```
Использование в командной строке (bsdtar)
```bash
Создание архива tar.gz
bsdtar -czf archive.tar.gz /path/to/directory
Распаковка архива zip
bsdtar -xf archive.zip
Просмотр содержимого архива 7z
bsdtar -tf archive.7z ```
Безопасность
libarchive уделяет большое внимание безопасности. В отличие от многих старых библиотек, она была спроектирована с учётом защиты от уязвимостей, характерных для архивов:
- Защита от переполнения буфера: Все операции с данными проверяются на границы буфера.
- Защита от path traversal (обхода директорий): libarchive проверяет, что пути в архиве не содержат
..или символических ссылок, ведущих за пределы целевой директории. - Защита от символических ссылок: При распаковке библиотека может следовать символическим ссылкам, но только если они ведут в пределах целевой директории.
- Защита от жёстких ссылок: libarchive проверяет, что жёсткие ссылки не ведут на файлы, которые не были созданы в рамках текущей распаковки.
- Обработка ошибок: Библиотека возвращает коды ошибок для всех операций, что позволяет разработчикам корректно обрабатывать некорректные или вредоносные архивы.
Несмотря на это, в libarchive периодически обнаруживаются уязвимости (например, CVE-2023-30571, CVE-2024-26256), которые оперативно исправляются разработчиками. Рекомендуется использовать последнюю стабильную версию.
Критика и ограничения
- Отсутствие поддержки RAR: libarchive не поддерживает формат RAR, что ограничивает её применение в некоторых сценариях.
- Сложность API: Для простых задач (например, распаковка одного файла) API может показаться избыточным.
- Производительность: В некоторых тестах libarchive уступает специализированным библиотекам (например,
zlibдля gzip,lzmaдля 7z) в скорости работы с определёнными форматами. - Ограниченная поддержка шифрования: libarchive поддерживает шифрование только для форматов ZIP (ZipCrypto и AES-256) и 7z (AES-256). Для других форматов шифрование не поддерживается.
Источники
- Официальная документация libarchive (libarchive.org)
- Исходный код проекта на GitHub (github.com/libarchive/libarchive)
- Статья «libarchive» в Википедии (английская версия)
- Документация FreeBSD по libarchive (freebsd.org)
- Список уязвимостей CVE, связанных с libarchive (cve.mitre.org)
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →