Skip to content

Accept a password for encrypted OOXML files instead of terminating at Encrypted #102

Description

@patriksimms

Summary

A password-protected .xlsx/.docx/.pptx always ends in ConvertError::Encrypted, and there is no way to supply the password. The rejection is precise and deliberate today: probe_ole (src/package/archive.rs) identifies the OLE container with EncryptionInfo/EncryptedPackage streams and returns Encrypted.

For a caller that has the password, the file is still unconvertible.

Why this matters

Document-ingestion pipelines (the LLM/RAG use case the README targets) receive password-protected spreadsheets and documents routinely, and the password is usually known: it arrived alongside the file.

Rust users can already work around this by composing the office-crypto crate with to_markdown_bytes:

let decrypted = office_crypto::decrypt_from_bytes(std::fs::read(path)?, "secret")?;
let md = anydoc::to_markdown_bytes(&decrypted, None)?;

But Node, Python, wasm, and CLI users have no equivalent: there is no solid OOXML-decryption library on those sides, so for the bindings the file is a dead end.

Proposed shape (narrowest version)

  • An optional password on the byte-level entry points, e.g. to_markdown_bytes(bytes, format, password: Option<&str>) or _with_password variants, mirrored in the bindings.
  • CLI: --password <pw> (plus perhaps an env-var fallback, since argv leaks into shell history and ps).
  • Where probe_ole currently returns Encrypted: if a password was supplied, decrypt via office-crypto and re-enter Format::from_bytes -> conversion with the plaintext. All existing resource limits then apply to the decrypted package unchanged. No password supplied, or wrong password: Encrypted, exactly as today.

office-crypto (v0.3.0) is pure Rust, its dependencies are all RustCrypto crates plus quick-xml (already a dependency here), and decryption needs no randomness, so the wasm target should be unaffected. Decryption cost is milliseconds.

Out of scope

  • Legacy encrypted .xls/.ppt (RC4 CryptoAPI): not supported by office-crypto; would keep returning Encrypted.
  • Encrypted ODF: a different scheme entirely; would keep returning Encrypted.

This issue was written with AI assistance (Claude Fable 5).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions