# `PhoenixKitAgent.Attachments.Unzip`
[🔗](https://github.com/BeamLabEU/phoenix_kit_agent/blob/v0.1.0/lib/phoenix_kit_agent/attachments/unzip.ex#L1)

Reads the parts of a workbook out of an uploaded zip without trusting it.

The sizes in a zip's central directory are written by whoever made the file:
a forged archive can say a part is a kilobyte and inflate to gigabytes, and
`:zip.extract/2` believes it. Here no declared size is believed. Each part is
inflated in chunks while the bytes produced are counted, against one budget
for the whole archive; the moment it is spent the reading stops with
`:too_large`, whatever the headers claimed. How many parts are read is
bounded too, so is the input read for one part (the archive's own size).

Only the parts a workbook is read from are taken (`[Content_Types].xml` and
the XML and relationship files under `xl/`); the rest (pictures, charts,
macros) is never inflated. `workbook/2` gives them back as a new, honest zip
made here, which is what `XlsxReader` opens.

# `failure`

```elixir
@type failure() :: :too_large | :unreadable
```

Why a workbook was not read.

# `read`

```elixir
@spec read(Path.t(), non_neg_integer()) ::
  {:ok, [{String.t(), binary()}]} | {:error, failure()}
```

The parts as `[{name, binary}]`, within `budget` bytes of inflated data.

# `workbook`

```elixir
@spec workbook(Path.t(), non_neg_integer()) :: {:ok, binary()} | {:error, failure()}
```

The workbook parts of the zip at `path`, inflated within `budget` bytes in
all, as the binary of a new zip.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
