cleverage/archive-process-bundle
CleverAge ArchiveProcessBundle integrates Archive handling into the ProcessBundle project, adding archive processing support to Symfony applications. Built for stable Symfony and LTS releases, it helps manage archived data within process workflows.
ZipTask and UnzipTask for CleverAge/ProcessBundle, plus a DI extension. It is a file-packaging step library, not a Doctrine-backed archive-entity system with retention policies or pluggable S3 adapters. Assumptions about ArchiveEntry entities, storage: filesystem|doctrine config, and immutable-archive semantics remain unsupported by the data and stay out of planning.UnzipTask as a Trust Boundary: archive_unzip now accepts max_files and max_size (default null = no limit) and validates entry count and total uncompressed size before extracting anything, failing with \RuntimeException on breach (#55). This promotes UnzipTask from "extract a file" to the enforcement point for untrusted inbound archives. It is still not a storage layer — it is a guard clause on an extraction step — but it materially changes where we place responsibility for input validation.ext-zip / ZipArchive extension. The v2.2 fixes (#17, #18) were entirely about ZipArchive open/write failure paths; v2.4 adds validation before those paths are reached, but does not remove the dependency.config/bundles.php); task wiring happens inside existing ProcessBundle process definitions. Two additive, optional options land on archive_unzip, both defaulting to null. No migration step is implied. Confirm against source before promising "zero migrations," but plan for none.ZipTask/UnzipTask throw \RuntimeException when an archive cannot be written or extracted. Workflows that "succeeded" while producing a broken archive will now fail.\UnexpectedValueException. Upstream steps passing strings break loudly.files_base_path semantics changed (#16) — only the leading occurrence is stripped (previously every occurrence), and an empty files_base_path now resolves relative paths correctly instead of from the filesystem root. Archive entry names may differ from pre-2.2 output.service: form, and bundle exceptions are documented in the reference pages. Any internal runbook or process definition copied from the old cookbook is now on a deprecated path — that is a documentation-migration item, not a code break, but it is the kind of thing that survives for years unnoticed.\RuntimeException. For any workflow accepting inbound archives, this is the single most valuable change in the release.null. Teams reading "zip-bomb protection added" may assume coverage that does not exist until someone sets the options. This is a documentation-and-defaults risk, not a code defect, and it is the likeliest source of a false sense of security.max_size too low and legitimate large archives now fail the workflow with \RuntimeException. Without per-workflow sizing data, a first-pass limit is a guess. Tighten from observed maxima, not from intuition.2.1 → 2.2 (or 2.1 → 2.4) jump. Treat as minor-version-with-behavioral-change: do not auto-merge.files_base_path fix can shift paths and break them with no code change on our side.ext-zip/libzip version differences between local, CI, and production containers remain the most likely source of divergent ZIP behavior (compression, overwrite, large-file handling). Note that uncompressed-size accounting is the basis of max_size — verify that the same archive trips (or does not trip) the limit consistently across environments.max_files/max_size. Internal-only packaging flows can leave the limits unset.max_size in bytes (and does it count uncompressed totals only, or archive size too)? What exactly does max_files count — regular files, directories too? Confirm against source/tests before setting values.UnzipTask throws \RuntimeException on a limit breach, does ProcessBundle retry, dead-letter, or halt? A retry loop on a deterministic zip-bomb rejection is pure waste — confirm we are not retrying non-transient failures.\RuntimeException, triage and alerting cannot separate "attacker sent a bomb" from "disk full."service: Usage: Do any of our process definitions still use the deprecated service: form flagged in #62? Migrate to task codes before it is removed.files_base_path fix may change them — can we diff old vs. new output before rollout?\UnexpectedValueException (#18).2.4.*? Will future releases continue to carry docs + tests per fix? Do we need a fork-on-failure plan given single-maintainer risk?ext-zip: Mandatory. Verify ZipArchive availability and libzip version in every environment, including CI images and production containers.ZipTask/UnzipTask as a reference implementation and reimplement in a Laravel job — the v2.2 and v2.4 tests are the spec to port, and the v2.4 limits should be ported by default, not optionally, since a reimplementation has no legacy-compatibility excuse.cleverage/archive-process-bundle:2.4.* — avoid floating constraints while behavior is settling.ext-zip present and consistent across local/CI/prod; ProcessBundle version compatible.files_base_path change makes byte-identical output not a safe assumption.max_files/max_size per task. Do not ship the upgrade with limits unset and call the security item closed.service:-based task references with task codes per the updated cookbook (#62), so internal docs stop diverging from upstream.TypeError handling for string inputs, should be deleted and replaced with explicit handling of \RuntimeException / \UnexpectedValueException.ZipArchive error codes appear in extraction failure messages.archive_unzip (max_files, max_size), both defaulting to null. Existing process definitions remain valid. Bundle registration and task wiring unchanged.service:; exceptions documented in reference pages. Documentation-alignment work, with a removal horizon to track.max_files/max_size, and add negative tests (oversized archive, entry-count breach) alongside the happy path.\RuntimeException path.files_base_path conventions, migrate service: references to task codes, add a pre-flight ext-zip check, and codify an archive-diff check in CI for packaging workflows.max_files/max_size are now operational thresholds, not static config. Legitimate archive sizes grow; a limit set today becomes a false-positive generator in a year. Review on the same cadence as capacity planning.ext-zip/libzip version pinning as a maintenance item alongside Composer dependencies; max_size depends on consistent uncompressed-size accounting.ZipArchive error codes; v2.4 adds a deterministic, pre-extraction rejection for limit breaches — a class of failure that previously appeared as a worker crash or a full disk. Confirm the limit-breach message is self-identifying.service: guidance, and documents bundle exceptions. Docs are now a reliable reference for 2.4+ specifically; pre-2.2 and pre-#62 internal notes are stale.UnzipTask limits give the team a named control to point at during security review — but only for workflows where they are configured. Keep an explicit inventory of which extraction steps are guarded and which are not.max_size and max_files — this converts an unbounded capacity risk into a plannable per-worker disk budget. Without limits configured, the prior unbounded risk stands unchanged.max_size should be sized against it.| Failure Scenario | Impact | Mitigation |
|---|---|---|
ZipTask cannot write archive (disk full, permissions) |
Step throws \RuntimeException; workflow halts (pre-2.2: silent bad artifact) |
Alert on the exception; pre-flight disk/permission checks in CI and deploy. |
UnzipTask cannot open/extract |
\RuntimeException with ZipArchive error code |
Map error codes in runbook; retry only on transient I/O codes. |
Inbound archive exceeds max_files / max_size |
Pre-extraction \RuntimeException; nothing written to disk |
Deterministic — do not retry. Alert as a security/abuse signal, not an infrastructure error. |
Limits left at default null |
No protection; prior unbounded resource-exhaustion risk remains | Inventory extraction steps that ingest untrusted input; set limits explicitly; track as a security control, not optional config. |
| Limits set too low | Legitimate archives rejected; workflow failures with no defect present | Baseline against observed p95/p99; review limits on a schedule; separate limit-breach alerting from I/O alerting. |
| Non-array input passed (string path) | \UnexpectedValueException |
Audit upstream step contracts; add schema validation before the task. |
| Multiple inputs with differing options | Pre-2.2 archives contained wrong options (fixed in #15) | Audit historical outputs for multi-input processes; regenerate where consequential. |
files_base_path semantics change |
Entry names differ from pre-2.2 output | Diff archives pre/post upgrade; validate downstream path consumers. |
Empty files_base_path with relative paths |
Previously resolved from filesystem root; now resolved correctly | Confirm configs; verify no workflow depended on the old (incorrect) resolution. |
Deprecated service: wiring still in use |
Breaks when the deprecated form is removed | Migrate to task codes per the updated cookbook (#62). |
ext-zip / libzip version drift |
Divergent compression/overwrite behavior; inconsistent max_size accounting across environments |
Pin extension versions in CI and production images. |
| Maintainer unresponsive on a future critical bug | Blocked on packaging capability | Fork-and-patch plan; test suite makes patching tractable. |
files_base_path, Options Precedence, and Now Limit Tuning: Three areas with active churn. Budget a focused review of the new tests plus the updated docs before letting the team configure limits independently — a poorly chosen max_size is a self-inflicted outage.ZipTask/UnzipTask — especially the limit-enforcement cases, (2) diff a real archive pre/post upgrade, (3) establish an archive-size baseline for one untrusted-input workflow and set limits on it, (4) write one integration test per workflow that uses packaging, including a rejection case, (5) only then expand to core workflows.max_files/max_size for them as a per-task guard with off-by-default semantics — not a platform-wide control — so it is not credited with coverage it does not have.How can I help you explore Laravel packages today?