OfficeCLI Document Size Limits and Large File Handling

OfficeCLI enforces strict resource limits defined in DocumentLimits.cs to prevent denial-of-service attacks from maliciously crafted Office files, including a 2 GiB uncompressed size cap, 100,000 zip entry limit, and 256-level recursion depth guard.

The OfficeCLI repository by iOfficeAI provides a command-line interface for processing Microsoft Office documents. When handling large files or potentially malicious archives, the tool implements comprehensive safety checks that balance legitimate large document processing with protection against zip bombs, decompression attacks, and stack overflow vulnerabilities.

Resource Limits Defined in DocumentLimits.cs

The DocumentLimits.cs file in the src/officecli/Core/ directory defines five critical constants that govern how OfficeCLI handles document size and complexity. These limits protect against specific attack vectors while allowing normal business documents to process unimpeded.

MaxRecursionDepth (256 levels)

The MaxRecursionDepth constant limits nesting depth for recursive document tree walks. This prevents stack overflow exceptions when processing deeply nested tables, group shapes, or formula groups. According to the source code, walkers in Word, PowerPoint, Excel, and the generic XML query call DocumentLimits.EnsureDepth(depth) to verify depth before recursion.

In GenericXmlQuery.cs, the depth check ensures that XML queries cannot trigger unbounded recursion. The WordHandler.HtmlPreview.Tables.cs file (line 32) demonstrates this protection when rendering HTML tables, checking depth on each nested table iteration.

MaxUncompressedBytes (2 GiB)

The MaxUncompressedBytes limit restricts the total uncompressed size of all entries in an OOXML zip package to 2 GiB. This defends against zip bombs that expand small compressed files into gigabytes of data. The check occurs in DocumentHandlerFactory.cs (lines 163-168) before the Open XML SDK touches the package, ensuring malicious files never reach the parser.

MaxZipEntries (100,000)

To prevent zip bombs containing millions of tiny parts, MaxZipEntries caps the number of entries inside an OOXML zip at 100,000. The DocumentHandlerFactory.cs validates this at lines 47-50, throwing a CliException with code "decompression_bomb" if exceeded.

MaxCompressionRatio (1,000:1)

Genuine Office files rarely exceed compression ratios of 100:1. MaxCompressionRatio sets an upper bound of 1,000, detecting archives that expand disproportionately. This verification runs in DocumentHandlerFactory.cs (lines 74-78) after scanning zip entries but before decompression.

RegexMatchTimeout (5 seconds)

User-supplied regular expressions run against document text with a RegexMatchTimeout of 5 seconds. This prevents catastrophic backtracking in regex patterns. The FindHelpers class respects this limit, ensuring commands like find or replace cannot hang indefinitely on complex patterns.

How OfficeCLI Enforces Limits Before Opening Files

The DocumentHandlerFactory.Open(filePath) method serves as the gateway for all document processing. This routine performs three critical validations before any Open XML SDK calls:

  1. Zip entry count verification – Ensures archive.Entries.Count does not exceed MaxZipEntries
  2. Total size calculation – Sums uncompressed sizes to verify the 2 GiB limit
  3. Compression ratio analysis – Compares uncompressed to compressed totals against the 1,000:1 threshold

When any check fails, the factory throws a CliException with a descriptive error code and user-facing suggestion:

throw new CliException(
    $"Cannot open {Path.GetFileName(filePath)}: package has {archive.Entries.Count} entries " +
    $"(limit {DocumentLimits.MaxZipEntries}); rejected as a potential decompression bomb.")
{
    Code = "decompression_bomb",
    Suggestion = "Verify the file is a genuine .docx/.xlsx/.pptx and not a crafted archive."
};

Runtime Protection Against Stack Overflow

The EnsureDepth method in DocumentLimits.cs provides additional protection beyond static limits. It uses RuntimeHelpers.TryEnsureSufficientExecutionStack() to probe the actual remaining stack space on thread-pool threads used by the resident/watch server.

This technique guarantees that even on small (~1 MiB) stacks, the process aborts cleanly before a real StackOverflowException occurs. The PowerPointHandler.HtmlPreview.Shapes.cs and FormulaParser.cs files implement this check during shape rendering and nested formula parsing respectively.

Practical Code Examples

Attempting to Open a Decompression Bomb

When a user tries to open a file exceeding the 2 GiB uncompressed limit:

$ officecli open huge.docx
Error: Cannot open huge.docx: uncompressed size exceeds 2 GiB; rejected as a potential decompression bomb.

Handling Deeply Nested Documents Programmatically

Applications using OfficeCLI as a library can catch specific exception codes:

try
{
    var handler = DocumentHandlerFactory.Open("deeply-nested.docx");
    var html = handler.RenderHtml();   // Internally calls EnsureDepth on each table/group
}
catch (CliException ex) when (ex.Code == "max_depth_exceeded")
{
    Console.Error.WriteLine($"Document too deeply nested: {ex.Suggestion}");
}

Regex Timeout Protection

For regex patterns that might cause catastrophic backtracking:

$ officecli find --regex "(a+)+b" --file large.docx
Error: Regex evaluation timed out after 5 seconds.

Summary

  • OfficeCLI implements five resource limits in DocumentLimits.cs to prevent malicious document attacks.
  • DocumentHandlerFactory.cs validates zip entries (100,000 max), uncompressed size (2 GiB), and compression ratio (1,000:1) before opening files.
  • Recursion depth is capped at 256 levels using EnsureDepth, which checks actual available stack space via RuntimeHelpers.TryEnsureSufficientExecutionStack().
  • Regex operations timeout after 5 seconds to prevent denial-of-service via backtracking.
  • All violations throw CliException with specific error codes and actionable suggestions rather than crashing the process.

Frequently Asked Questions

What is the maximum file size OfficeCLI can process?

OfficeCLI supports documents up to 2 GiB uncompressed and 100,000 zip entries within the OOXML package. These limits are enforced in DocumentHandlerFactory.cs before any content parsing begins, protecting against zip bombs while accommodating legitimate large documents.

How does OfficeCLI prevent stack overflow when processing complex documents?

The tool uses RuntimeHelpers.TryEnsureSufficientExecutionStack() in the EnsureDepth method to probe remaining stack space before recursive operations. This check runs in WordHandler, PowerPointHandler, ExcelHandler, and FormulaParser.cs to ensure the 256-level MaxRecursionDepth never causes actual stack overflow exceptions.

Can I adjust the document size limits or timeout values?

The constants in DocumentLimits.cs are compiled into the assembly. To modify limits such as MaxUncompressedBytes, MaxZipEntries, or RegexMatchTimeout, you must rebuild the source after adjusting the values in the DocumentLimits class definition.

What error message appears when a file exceeds OfficeCLI limits?

The CLI throws a CliException with a specific error code (e.g., "decompression_bomb" or "max_depth_exceeded") and a user-friendly suggestion. For example, oversized packages return: "Cannot open [filename]: uncompressed size exceeds 2 GiB; rejected as a potential decompression bomb."

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 →