Read ZIP, RAR, and 7z archives into memory, backed by a Rustler NIF.
Extraction only — this library never creates archives (the RAR backend's
license forbids it, and reading is all it exists for). The format is
detected from the file's magic bytes, never from its name, so a .cbz
that is secretly a RAR extracts fine.
All entries are returned in memory as {name, data} tuples, in archive
order. Directory entries are skipped. Nothing is ever written to disk, so
hostile entry names (../../etc/passwd) cannot escape anywhere — but do
treat names as untrusted input if you persist them.
Example
{:ok, entries} = LangelicArchive.extract("comic.cbr")
Enum.map(entries, fn {name, data} -> {name, byte_size(data)} end)Decompression-bomb guard
Extraction fails with an :too_large error once the cumulative unpacked
size exceeds :max_total_bytes (default 4294967296
bytes — 4 GiB). Raise or lower it per call:
LangelicArchive.extract(path, max_total_bytes: 100 * 1024 * 1024)
Summary
Functions
Detect the archive format from the leading magic bytes.
Extract every file entry of the archive at path into memory.
Extract archive content already held in memory.
List the file entries of the archive at path without decompressing them.
List the file entries of archive content already held in memory.
Types
Functions
Detect the archive format from the leading magic bytes.
Accepts the archive's binary content (a prefix is enough). Returns
:unknown for anything that is not a ZIP, RAR (v4 or v5), or 7z archive.
@spec extract( Path.t(), keyword() ) :: {:ok, [entry()]} | {:error, LangelicArchive.Error.t()}
Extract every file entry of the archive at path into memory.
Returns entries as {name, data} tuples in archive order. Directory
entries are skipped.
Options
:max_total_bytes— abort with:too_largeonce cumulative unpacked size exceeds this (default 4 GiB).
@spec extract_binary( binary(), keyword() ) :: {:ok, [entry()]} | {:error, LangelicArchive.Error.t()}
Extract archive content already held in memory.
The RAR backend can only read from the filesystem, so the data is staged
through a temporary file (removed before returning). Prefer extract/2
when the archive is already on disk.
@spec list(Path.t()) :: {:ok, [{String.t(), non_neg_integer()}]} | {:error, LangelicArchive.Error.t()}
List the file entries of the archive at path without decompressing them.
Returns {name, unpacked_size} tuples in archive order.
@spec list_binary(binary()) :: {:ok, [{String.t(), non_neg_integer()}]} | {:error, LangelicArchive.Error.t()}
List the file entries of archive content already held in memory.