Skip to content

test(docx-core): corpus differential-testing harness + LibreOffice cross-process lock - #876

Draft
stevenobiajulu wants to merge 1 commit into
mainfrom
tweak-corpus-harness-20260815
Draft

test(docx-core): corpus differential-testing harness + LibreOffice cross-process lock#876
stevenobiajulu wants to merge 1 commit into
mainfrom
tweak-corpus-harness-20260815

Conversation

@stevenobiajulu

Copy link
Copy Markdown
Member

DRAFT — investigation output. Do not auto-merge.

Corpus-scale differential/fuzz testing of safe-docx over a 520-document SHA-256-pinned corpus (open-agreements CC-BY, docx-platform-tests Apache-2.0, dotnet/Open-XML-SDK MIT, SuperDoc docx-corpus ODC-BY, LibreOffice fuzzer seeds). No document bytes are committed; the manifest holds only hashes, URLs, licenses, and a derived OOXML feature index.

What this PR adds (no shipping-engine behavior change)

  • scripts/corpus/ — opt-in harness: pinned manifest + fetch script + feature classifier + a deterministic synthetic OOM reproduction, plus a per-source licensing determination and a privacy-safe investigation report. Gated like SAFE_DOCX_REAL_CORPUS_DIR; no default CI job.
  • packages/docx-coreacquireGlobalSofficeLock: a machine-wide lockfile serializing every LibreOffice oracle/probe launch so parallel workers/sessions can't spawn concurrent headless soffice (the Investigate LibreOffice macOS headless startup crashes and parallel probe amplification #627 amplification vector). Pure unit test included (no soffice needed).

Findings from the run (filed; not fixed here)

# Finding Mode Status
#874 computeAtomLcs allocates an O(n·m) DP matrix → heap OOM/SIGABRT on a single large paragraph (~12k atoms @ 2 GB; a real fuzzer seed @ 4 GB) both filed, synthetic repro committed
#875 BOM-prefixed document.xml (ISO-Strict exports, 56/121 MS files) throws a raw xmldom ParseError from load + compare instead of loading/failing closed both filed, minimal repro in issue
#742 rebuild mode unwraps pre-existing tracked changes → bare <w:delText> (Word-unreadable) rebuild only mechanism + repro commented
#627 12 live leaked headless soffice processes (1–2 day, 0% CPU, hung after startup); child outlives parent's profile cleanup live evidence posted

Invariant results

Every inplace self-comparison and metamorphic pair satisfied reject→original / accept→revised across the corpus; all substantive mismatches were rebuild-only and reduced to #742/#875-class. Aspose oracle was licensed and verified non-watermarked after pinning aspose-words==25.10.0 (the swallowed-license defect in aspose_compare.py is documented in the report).

See scripts/corpus/INVESTIGATION_REPORT.md for full counts, licensing determination, and the recommended next queue.

…ice cross-process lock

Investigation deliverables for corpus-scale differential/fuzz testing. No behavior
change to shipping engine code; adds an opt-in corpus harness, a cross-process
LibreOffice oracle lock, and minimized synthetic reproductions.

Harness (scripts/corpus/, all opt-in, no default CI job, no document bytes committed):
- differential-corpus-manifest.json: 520 SHA-256-pinned entries across five sources
  with a derived OOXML feature index (the only committed corpus content).
- classify_docx_features.mjs: OOXML feature classifier producing the derived index.
- fetch_differential_corpus.mjs: pins-and-fetches into a local cache, extending the
  prepare_real_comparison_corpus.mjs pattern (gated like SAFE_DOCX_REAL_CORPUS_DIR).
- generate_oom_repro.mjs: deterministic synthetic reproduction for #874.
- README.md + INVESTIGATION_REPORT.md: per-source licensing determination and a
  privacy-safe run summary.

LibreOffice oracle (packages/docx-core):
- Add acquireGlobalSofficeLock: a machine-wide lockfile serializing every soffice
  launch (probe + oracle) so parallel workers/sessions cannot spawn concurrent
  headless LibreOffice — the amplification vector behind #627. Stale locks whose
  holder PID is dead are stolen. Path/poll are parameterized for unit testing.
- libreoffice-oracle-lock.test.ts: pure unit coverage (exclusive acquire, contention,
  stale-steal) with no soffice launch.

Findings filed from the run: #874 (O(n*m) LCS matrix OOM), #875 (BOM-prefixed
document.xml raw ParseError), mechanism for #742 (rebuild unwraps pre-tracked changes),
and live #627 leaked-process evidence.

Ref: #874
Ref: #875
Ref: #627
@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
site Ready Ready Preview Aug 16, 2026 4:25am

Request Review

@github-actions github-actions Bot added the test label Aug 16, 2026
}

record.strict =
doc.includes(W_STRICT_NS) || (contentTypes ?? '').includes('purl.oclc.org/ooxml');
@codecov

codecov Bot commented Aug 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants