This release adds 1 notable feature for engineering teams evaluating rollout.
✓ No known CVEs patched in this version
Topics
+5 more
Summary
AI summaryUpdates What's new, NEW, and width across a mixed release.
Full changelog
What's new
SKILL.md: Word for Mac hard-open failure causes (5 patterns)
This release documents five distinct causes of "Word experienced an error trying to open the file" on Word for Mac, discovered through systematic binary-search debugging of a production report generator. Windows Word is more forgiving about all five.
1. w:fldChar / w:instrText packed into one <w:r>
Every field code element must be in its own separate <w:r>. Packing begin/instrText/end into one run is schema-invalid and triggers a hard open failure on Mac.
2. w:titlePg without a matching first-page header/footer
Declaring <w:titlePg/> in sectPr without also providing a w:headerReference type="first" causes Mac Word to refuse the file.
3. PNG relationship before header/footer relationships in document.xml.rels
An undocumented Mac Word constraint: any PNG image relationship that appears before header/footer relationships in word/_rels/document.xml.rels causes a hard open failure. JPEG is fine. Fix: access section.header/section.footer before any add_picture() call.
4. w:abstractNum after w:num in numbering.xml
CT_Numbering is a strict OOXML sequence — all w:abstractNum elements must precede all w:num elements. Merging custom numbering into a template via naive .append() violates this.
5. wp:extent cx/cy values in the billions (NEW)
Word for Mac refuses files where any <wp:extent> attribute is in the billions or trillions of EMUs (normal range: 1–10 million). Two distinct root causes:
Cause A — PIL BytesIO without DPI metadata:
# WRONG — no DPI → python-docx gets DPI≈0 → cx/cy in trillions
img.save(buf, format='JPEG', quality=92)
# CORRECT
img.save(buf, format='JPEG', quality=92, dpi=(96, 96))
Cause B — double Inches() conversion:
A helper that calls Inches(width) internally receives a pre-converted EMU value. Tell-tale fingerprint: 4,849,538,688,000 = 5,303,520 × 914,400. Fix: pass float inches to such helpers, never a pre-converted EMU constant.
Detection script (added to SKILL.md):
import zipfile; from lxml import etree
with zipfile.ZipFile("file.docx") as z:
tree = etree.fromstring(z.read("word/document.xml"))
WPD = 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing'
for i, ext in enumerate(tree.iter(f'{{{WPD}}}extent')):
if int(ext.get('cx', 0)) > 100_000_000:
print(f"Drawing {i}: cx={int(ext.get('cx')):,} *** OVERSIZED")
No server code changes
This is a documentation-only patch. No API or behaviour changes.
uvx docx-mcp-server # always pulls latest
Full Changelog: https://github.com/SecurityRonin/docx-mcp/compare/v0.7.3...v0.7.4
Full Changelog: https://github.com/SecurityRonin/docx-mcp/compare/v0.7.3...v0.7.4
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About SecurityRonin/docx-mcp
Read and edit Word (.docx) documents with track changes, comments, footnotes, and structural validation. The only MCP server combining w:ins/w:del tracked changes, threaded comments, and footnotes with OOXML-level paraId validation and document auditing. 18 tools, Python 3.10+.
Related context
Related tools
Earlier breaking changes
- v0.6.1 Empty `document_handle` resolves to `__default__` slot, maintaining backward compatibility.
Beta — feedback welcome: [email protected]