@@ -7,20 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
77
88## [ Unreleased]
99
10+ ## [ 0.2.1] — 2026-04-24
11+
1012### Security
1113
12- - Bound ZIP entry reads in EPUB, PPTX, and DOCX parsers. A crafted archive
13- declaring a tiny compressed size could previously expand to multi-GB on
14- decompression; entries are now rejected when the declared or observed
15- decompressed size exceeds a per-entry cap.
14+ - Introduce a shared ` SafeArchive ` in ` paperjam-model::zip_safety `
15+ (behind the ` zip_safety ` feature) and route the EPUB and PPTX parsers
16+ through it. Decompression is bounded on four axes — per-entry
17+ decompressed size (100 MB), total decompressed bytes per archive
18+ (500 MB), entry count (10 000), and compression ratio (100×) — so a
19+ crafted archive can no longer expand to multi-GB or exhaust the entry
20+ table. Replaces the per-crate ` safe_read ` copies from 0.2.0.
1621- Cap ` Vec::with_capacity ` preallocations in XLSX sheet parsing and PPTX
1722 slide parsing at reasonable ceilings so attacker-controlled counts can
1823 no longer trigger large allocations up front.
1924- ` paperjam-mcp ` : resolved paths are now sandboxed to the configured
2025 working directory by default. Absolute paths and ` .. ` traversal that
21- escape the working dir are rejected with a structured error. Operators
22- can opt out with ` --allow-absolute-paths ` (or
23- ` ServerConfig::allow_absolute_paths ` ).
26+ escape the working dir are rejected with a structured error
27+ ( ` McpError::PathEscapesSandbox ` ). Operators can opt out with
28+ ` --allow-absolute-paths ` (or ` ServerConfig::allow_absolute_paths ` ).
2429
2530### Fixed
2631
@@ -46,21 +51,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
4651
4752### Changed
4853
54+ - MSRV is now declared and enforced at ** Rust 1.88** . ` Cargo.lock ` is
55+ committed and the MSRV CI job runs ` cargo check --workspace --locked `
56+ so the declared minimum stays deterministic until a deliberate
57+ ` cargo update ` . Keep ` rust-version ` in ` Cargo.toml ` and
58+ ` RUSTUP_TOOLCHAIN ` in ` .github/workflows/ci.yml ` in sync.
4959- ` paperjam-async ` no longer force-enables ` signatures ` and ` validation `
5060 on ` paperjam-core ` . Consumers that need them (e.g. ` paperjam-py ` )
5161 continue to enable them explicitly; lightweight async users no longer
5262 drag in the full signing / validation stack.
63+ - Pin ` md-5 = "0.10" ` in ` paperjam-core ` to collapse a duplicate
64+ RustCrypto ` digest ` chain pulled in via ` md-5 = "0.11" ` .
5365- Docs site CI now builds on pull requests (without deploying) so docs
54- regressions are caught pre-merge. Binaryen's ` wasm-opt ` is installed
55- so release WASM bundles are size-optimized.
66+ regressions are caught pre-merge. Binaryen's ` wasm-opt ` is pinned to
67+ ` version_119 ` (downloaded with SHA-256 verification and cached) and
68+ invoked with the full set of rustc-emitted wasm features
69+ (` bulk-memory ` , ` sign-ext ` , ` nontrapping-float-to-int ` ,
70+ ` mutable-globals ` , ` reference-types ` , ` multivalue ` ) so release WASM
71+ bundles are size-optimized on modern toolchains.
72+ - CI rust-cache is scoped with ` shared-key ` across the Python matrix and
73+ ` save-if: github.ref == 'refs/heads/main' ` on non-lint jobs, keeping
74+ the cache quota stable.
5675
5776### Docs
5877
5978- README: CLI examples now use the correct ` pj ` binary name and accurate
6079 flags; removed the nonexistent ` extract tables --format csv ` flag.
6180- ` docs-site/docs/getting-started/installation.md ` : replace leftover
6281 Sphinx build instructions with the Docusaurus workflow, fix the
63- clone org, expand the feature-flag table.
82+ clone org, expand the feature-flag table, and bump the
83+ build-from-source Rust requirement to 1.88+.
6484- ` pyproject.toml ` : fill in multi-format description, ` readme ` ,
6585 ` project.urls ` , and extra classifiers/keywords so the PyPI page is
6686 populated. Drop the stale Sphinx ` [docs] ` extra.
0 commit comments