Skip to content

fix(documents): bound DOCX table rendering - #184

Merged
chaliy merged 2 commits into
mainfrom
codex/docx-table-bounds
Oct 13, 2026
Merged

chaliy merged 2 commits into
mainfrom
codex/docx-table-bounds

Conversation

@chaliy

@chaliy chaliy commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

What changed

Both local DOCX backends admit table dimensions and padded-cell work before rendering: at most 1,000 rows, 50 columns and 50,000 padded cells. The deprecated Office converter also admits exact escaped UTF-8 output bytes into one 10 MiB buffer before padding or allocation, preserving normal headers, sparse-row padding, empty-row removal and escaping.

The default markkit backend preflights the conventional main part and internal relationship-selected main parts, including merged-cell spans and nested tables. It honors tighter configured archive budgets. No new dependency versions or public API fields.

The shared legacy table writer also caps each spreadsheet table at 10 MiB. The hardening guide and canonical contracts document this ceiling and markkit preflight's 50-level table nesting cap.

Why

Archive/input caps did not constrain the row-count × widest-row expansion. Final response truncation happened after allocation. Moving to markkit changed the default backend but retained this table-padding concern in both selectable implementations.

Before / After

Ordinary offline fixture: two rows, three columns, four populated cells; injected limits of one row, two columns, five padded cells, or 32 output bytes.

Before enforcement:

docx_table_limits_admit_before_rendering ... FAILED
called Result::unwrap_err() on an Ok value:
| A | B | C |
| --- | --- | --- |
| D |  |  |
docx_preflight_admits_small_table_dimensions ... FAILED

After:

docx_table_limits_admit_before_rendering ... ok
docx_table_limits_preserve_ordinary_padding ... ok
docx_table_bytes_include_escaping_and_document_blocks ... ok
docx_preflight_admits_small_table_dimensions ... ok
docx_preflight_counts_spans_nested_and_multiple_tables ... ok

Existing normal DOCX heading/list/table assertions and offline tool/fetch conversion pass. Added a normal DOCX whose main XML lives at a relationship-selected nonstandard path. No large archive/table or memory-exhaustion experiment was run.

Risk

  • Medium: documents above these table limits now fail this converter and may fall through to another configured backend. DOCX gains an extra bounded XML preflight.
  • markkit's other text/markup and parser allocations remain subject to input/archive budgets and final response truncation; this change bounds table padding and does not claim process-wide memory isolation.

Checklist

  • Unit tests are passed: unchanged workspace tests; focused ordinary DOCX contracts with docs-office.
  • Smoke tests are passed: normal DOCX through the offline tool and default fetcher; legacy converter headings/lists/tables.
  • Documentation is updated: hardening guide and changelog.
  • Knowledge is up to date and not in conflict: tool contract, fetcher design, TM-DOS-008 and both OKF checks.

Validation: formatter; workspace Clippy with -D warnings; Office-only Clippy; warning-free workspace rustdoc; publishable workspace release build. CI workflows are unchanged.

@chaliy
chaliy merged commit 3ea9265 into main Oct 13, 2026
12 checks passed
@chaliy
chaliy deleted the codex/docx-table-bounds branch October 13, 2026 01:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant