How LiteParse Handles Encrypted and Password-Protected PDFs

LiteParse delegates encryption handling to the underlying PDFium library, exposing password support through the LiteParseConfig struct and propagating PDFium's PasswordRequired or InvalidPassword errors when credentials are missing or incorrect.

LiteParse, the high-performance document parsing library from the run-llama organization, provides native support for encrypted and password-protected PDFs across all language bindings. Unlike parsers that fail silently or require manual decryption steps, LiteParse accepts an optional password parameter that flows through its Rust core directly into PDFium's FPDF_LoadDocument API. This design ensures that handling encrypted PDFs in LiteParse requires no additional dependencies or pre-processing scripts.

The Architecture of Password Handling in LiteParse

The password workflow follows a clear path from user input to PDFium's C API, with explicit error handling at every layer.

Configuration Layer (config.rs)

The entry point for password support is the LiteParseConfig struct defined in crates/liteparse/src/config.rs. This struct includes a pub password: Option<String> field that captures the user-provided credential:

// From crates/liteparse/src/config.rs
pub struct LiteParseConfig {
    pub password: Option<String>,
    // ... other configuration fields
}

When instantiated, the parser stores this optional password for downstream use.

Parser Integration (parser.rs)

During document loading, the parser invokes extract::load_document_from_input in crates/liteparse/src/parser.rs. This function extracts the password from the configuration using self.config.password.as_deref(), converting the Option<String> into an Option<&str> suitable for FFI boundaries:

// Simplified flow in crates/liteparse/src/parser.rs
let password_ref = self.config.password.as_deref();
load_document_from_input(input, password_ref)

PDFium Bridge (library.rs)

The pdfium crate bridges Rust to the native PDFium library. In crates/pdfium/src/library.rs, the Pdfium::load_document method forwards the optional password pointer to the C function FPDF_LoadDocument. When the password is None, LiteParse passes a null pointer to PDFium, signaling an unencrypted document or a request to check for encryption:

// Signature from crates/pdfium/src/library.rs
impl Pdfium {
    pub fn load_document(&self, path: &str, password: Option<&str>) -> Result<Document, PdfiumError> {
        // Calls FPDF_LoadDocument with password pointer or null
    }
}

Error Propagation (error.rs)

PDFium returns specific error codes for encryption scenarios, which LiteParse maps to typed errors in crates/pdfium/src/error.rs:

  • PdfiumError::PasswordRequired — Returned when the PDF requires a password but None was provided
  • PdfiumError::InvalidPassword — Returned when the supplied password fails decryption

These errors bubble up through the call stack unchanged, allowing CLI tools and language bindings to present actionable feedback to users.

Working with Encrypted PDFs Across All Interfaces

LiteParse exposes password functionality consistently across its CLI, Node.js, Python, and Rust APIs.

Command Line Interface (main.rs)

The CLI binary defined in crates/liteparse/src/main.rs accepts a --password flag that populates the configuration before parsing begins:

liteparse encrypted_report.pdf --output json --password "mySecret123"

If the password is incorrect or omitted for an encrypted file, the CLI prints the corresponding PDFium error and exits with a non-zero status.

Node.js and TypeScript

The Node.js wrapper in packages/node/src/lib.ts accepts a password option in the constructor, passing it through to the Rust core:

import { LiteParse } from "liteparse";

const parser = new LiteParse({
  password: "mySecret123",
  output: "json"
});

const result = await parser.parseFile("encrypted.pdf");
console.log(result);

Python API

The Python binding in packages/python/liteparse/parser.py maps the password argument to the underlying config:

from liteparse import LiteParse

parser = LiteParse(password="mySecret123", output="json")
result = parser.parse_file("encrypted.pdf")
print(result)

Direct Rust Usage

For Rust developers using the library directly, instantiate LiteParseConfig with the password field:

use liteparse::{LiteParse, LiteParseConfig};

let cfg = LiteParseConfig {
    password: Some("mySecret123".to_string()),
    ..Default::default()
};

let parser = LiteParse::new(cfg);
let result = parser.parse_path("encrypted.pdf")?;
println!("{:?}", result);

Rendering and Conversion Support

Beyond text extraction, password support extends to document transformation pipelines. The conversion utilities in crates/liteparse/src/conversion.rs and rendering functions in crates/liteparse/src/render.rs both accept the same Option<&str> password argument. This allows encrypted PDFs to undergo OCR processing or format conversion without requiring intermediate decryption files.

Summary

  • LiteParse stores passwords in LiteParseConfig.password as an Option<String> (crates/liteparse/src/config.rs)
  • The parser forwards credentials to PDFium via load_document in crates/pdfium/src/library.rs
  • PDFium's FPDF_LoadDocument receives the password pointer, returning PasswordRequired or InvalidPassword errors when appropriate
  • All interfaces—CLI (--password), Node.js, Python, and native Rust—support the same password configuration pattern
  • Rendering and conversion pipelines reuse the same authentication flow for encrypted source documents

Frequently Asked Questions

What happens if I don't provide a password for an encrypted PDF?

LiteParse returns a PdfiumError::PasswordRequired error (defined in crates/pdfium/src/error.rs) and aborts the parsing operation. The CLI displays a user-friendly error message, while library bindings propagate the error to the caller for handling.

Can LiteParse crack or bypass PDF encryption?

No. LiteParse relies entirely on PDFium's standard security handler and only attempts decryption when provided with the correct user or owner password. It does not implement brute-force attacks, dictionary attacks, or proprietary decryption bypasses.

Is the password stored in memory after parsing completes?

The password exists as a String inside LiteParseConfig for the duration of the parser's lifetime. When the LiteParse instance is dropped, the memory containing the password is released according to Rust's ownership rules. The password is never written to log files or output metadata.

Does password protection affect parsing performance?

Decryption adds negligible overhead during the initial FPDF_LoadDocument call, but does not impact subsequent text extraction, OCR, or rendering operations once the document handle is established. Performance characteristics remain identical to unencrypted PDFs after successful authentication.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →