Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Design & Guarantees

The promises the extension makes, and the engineering behind them.

In-memory, in-process, no I/O

Every operation takes byte buffers and returns byte buffers. The underlying c2pa crate is compiled with default-features = false:

  • no file_io — the extension cannot read or write files;
  • no fetch_remote_manifests — a manifest that points at a remote store is not fetched; there are no trust-list downloads; and signing passes no timestamp-authority URL.
  • rust_native_crypto — cryptography is pure Rust (no OpenSSL linkage), so the built library is portable across systems with differing SSL stacks.

The result: validating or signing an image is a bounded, stateless function call. Nothing warms up, nothing persists, nothing talks to the outside world. That makes the extension predictable inside a web request — the original design constraint, coming from the WordPress upload pipeline.

Byte-safety across the PHP ↔ Rust boundary

Image bytes are not valid UTF-8, and treating them as text corrupts them. On the Rust side every byte parameter is ext_php_rs::binary::Binary<u8> — a byte-preserving view of the PHP string — never a Rust String. On the PHP side you pass ordinary strings; PHP strings are already binary-safe. The practical rule: hand bytes straight from file_get_contents() (or your storage layer) to the extension and back, with no encoding layer in between.

Threading and SAPI posture

The extension is built and tested for PHP 8.3–8.5 NTS on Linux (x86_64, arm64) and macOS (arm64); ZTS is declared supported but not yet exercised in CI (no ZTS runner in the release matrix). It holds no global mutable state: each Reader/Builder/Signer is an independent value, so concurrent requests in any SAPI are fine.

Error philosophy

One exception class (C2paException), typed error variants internally, and a hard line between verdicts and errors: an unsigned image or a failed validation is a verdict (a normal return), while corrupt input or a misconfigured signer is an error (an exception). See Errors.

Versioning and releases

The crate follows semver via git tags (v*); each tag’s CI run builds the full platform × PHP-minor matrix and attaches:

  • PIE-convention extension tarballs per leg, and
  • a transitive third-party license manifest (cargo about) covering everything statically linked into the binaries.

Dependency versions are pinned exactly (=x.y.z) — upgrades are deliberate, tested bumps, never silent drift.

Licensing

GPL-2.0-or-later, © Automattic, Inc. — consistent with WordPress core. The “or later” clause is load-bearing: the c2pa and ext-php-rs dependencies are Apache-2.0/MIT, and Apache-2.0 is GPLv3-compatible, so distributing the combined work exercises the GPLv3 option.

Scaffolding

The repository is a child of DisplaceTech/ext-template: the build system, CI, docs, and release workflows are template-managed and re-rendered with its bin/sync (driven by .ext-template.conf at the repo root); the Rust sources, stubs, and this book are the extension’s own.