Открыть сервис

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 построена на модульной архитектуре, основанной на концепции «фильтров» и «форматов». Это позволяет библиотеке обрабатывать данные в несколько этапов:

  1. Чтение/запись базового потока: Библиотека работает с произвольным потоком данных (файл, сокет, память), а не с файловой системой напрямую. Это обеспечивает поддержку потоковой архивации.
  2. Фильтры сжатия: libarchive поддерживает цепочки фильтров, которые применяются к данным до или после их чтения/записи. Поддерживаются алгоритмы: gzip, bzip2, lzip, lzma, xz, compress, lz4, zstd и brotli. Фильтры могут быть вложенными (например, архив tar.gz обрабатывается как фильтр gzip, применённый к формату tar).
  3. Форматы архивов: Библиотека содержит модули для каждого поддерживаемого формата. Каждый модуль отвечает за разбор заголовков, извлечение записей (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: пустой формат (для тестирования).
  1. 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 Linux bsdtar является стандартной утилитой для работы с пакетами.
  • 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). Для других форматов шифрование не поддерживается.

Источники

  1. Официальная документация libarchive (libarchive.org)
  2. Исходный код проекта на GitHub (github.com/libarchive/libarchive)
  3. Статья «libarchive» в Википедии (английская версия)
  4. Документация FreeBSD по libarchive (freebsd.org)
  5. Список уязвимостей CVE, связанных с libarchive (cve.mitre.org)

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →