Add text/plain asset handler via c2pa-text crate#2117
Conversation
Add a TextIO asset handler that embeds and extracts C2PA JUMBF manifests in plain text files using the c2pa-text crate. The crate encodes binary manifest data as invisible Unicode Variation Selectors, following the C2PA text embedding specification (Section A.7). The handler implements CAIReader, CAIWriter, and AssetPatch for full read/write/patch support. Hash object positions span the entire text content with an exclusion range covering the embedded manifest bytes. Registers "txt" and "text/plain" as supported types in the MIME utility and adds TextIO to all three handler maps (readers, writers, file-based). The c2pa-text reference implementation is at: https://github.com/encypherai/c2pa-text
|
A few things I noticed:
|
Git dependencies are rejected by crates.io during publish. c2pa-text v1.1.0 is already published on crates.io, so reference it directly.
|
@dcondrey Thanks for the close read. Addressed inline: 1. Git dependency. You're right - crates.io rejects git sources. 2. NFC normalization. The 3. AssetPatch. Good catch - the original PR description was wrong. The handler implements 4. Byte offsets. 5. Additional text/ subtypes. Agreed this is worth considering. Starting with |
Summary
Adds a
TextIOasset handler fortext/plainfiles, implementing C2PA manifest read, write, and remove support for plain text assets per Section A.7 of the C2PA specification.The handler uses the c2pa-text reference implementation crate, which encodes JUMBF manifest bytes as invisible Unicode Variation Selectors. This encoding is reversible, preserves the visible text content, and survives copy-paste in most environments.
Changes
sdk/src/asset_handlers/text_io.rs(new):TextIOstruct implementingCAIReader,CAIWriter, andAssetIO. Hash object positions cover the full text with an exclusion range for the embedded manifest.sdk/src/asset_handlers/mod.rs: Registertext_iomodule.sdk/src/jumbf_io.rs: AddTextIOto reader, writer, and test handler lists.sdk/src/utils/mime.rs: Maptxtextension andtext/plainMIME type.sdk/Cargo.toml: Addc2pa-textdependency (crates.io v1.1.0).Notes
c2pa-textcrate in bothembed_manifestandextract_manifest.ExtractionResult.offsetandExtractionResult.lengthare byte offsets (via Rust'schar_indices()), matching the byte-levelHashObjectPositionscontract.AssetPatchis not implemented in this PR. Thec2pa-textcrate'sencode_wrapper_paddedfunction supports fixed-size wrappers for in-place patching, but wiring that up is deferred to a follow-up.Context
C2PA Section A.7 defines text as a supported asset type. The
c2pa-textcrate provides the encoding layer. This handler integrates it into c2pa-rs so that plain text files can be signed and verified the same way as images, audio, and video.Encypher co-chairs the C2PA text task force and maintains the
c2pa-textreference implementation.Test plan
cargo testpasses with text_io registered in all handler maps.txtfile, read back viaReader, verify manifest integritytext/plainandtxtresolve correctly in MIME utility functions