Skip to content

fix: prevent corrupt docx export for legacy w:pict vml rect content#2905

Merged
harbournick merged 2 commits intomainfrom
artem/SD-2652
Apr 22, 2026
Merged

fix: prevent corrupt docx export for legacy w:pict vml rect content#2905
harbournick merged 2 commits intomainfrom
artem/SD-2652

Conversation

@artem-harbour
Copy link
Copy Markdown
Contributor

@artem-harbour artem-harbour commented Apr 22, 2026

Linear: SD-2652

Fixes issue where import→export of DOCX files containing legacy w:pict/v:rect could produce invalid mc:AlternateContent with empty w:drawing, causing Word corruption errors.

What changed:

  • Preserved legacy VML metadata on contentBlock (vmlAttributes, style) to avoid attribute loss during PM normalization.
  • Added legacy VML routing guard in translateContentBlock() so contentBlock with VML markers exports via w:pict/v:rect path.
  • Hardened mc:AlternateContent decode:
    • returns null for missing/invalid drawing content,
    • emits mc:Fallback for valid alternate-content branches.
  • Added/updated unit tests for new routing and decode behavior.

@linear
Copy link
Copy Markdown

linear Bot commented Apr 22, 2026

@github-actions
Copy link
Copy Markdown
Contributor

Status: PASS

The structural OOXML is sound. Here's what I checked and found:

mc:AlternateContent / mc:Choice / mc:Fallback (ECMA-376 Part 3, §10.2)

The newly emitted structure is valid:

  • mc:Choice carries an unprefixed Requires attribute — required by §10.2.2, correctly spelled and not prefixed. ✓
  • mc:Fallback has no attributes — §10.2.3 makes no attributes required. ✓
  • mc:Fallback appears after mc:Choice — §10.2.1 mandates this ordering. ✓
  • Only one mc:Fallback is produced. ✓

w:drawing content model

hasValidDrawingContent gates decode on wp:inline or wp:anchor being present, which matches the CT_Drawing content model exactly (§17.3.3.9, §20.4.2.3, §20.4.2.8). An empty or non-drawing drawingContent correctly short-circuits to null. ✓

w:pict / VML detection in translate-content-block.js

The detectLegacyVmlRectMarkers heuristics (fillcolor, stroked, o: prefix, inline style) all correspond to real VML element attributes defined in ECMA-376 Part 4 / the VML schema. The routing logic is correct. ✓


One thing worth noting, though not a spec violation: the mc:Fallback is a carbonCopy of the same w:drawing content in the choice. The fallback's purpose per §10.2.3 is to serve consumers that can't process the Requires="wps" namespaces — but those same consumers would encounter the same wps: elements inside the copied fallback. In practice this is fine because Word documents declare mc:Ignorable="wps" at the document root, letting non-wps consumers silently skip those elements. But if you ever want a conformance-clean export, the proper fallback for a wps-requiring shape is legacy VML (w:pict with v:shape). For now it's not a blocker. See https://ooxml.dev/spec?q=mc:Fallback for the §10.2.3 discussion.

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@artem-harbour artem-harbour self-assigned this Apr 22, 2026
@artem-harbour artem-harbour marked this pull request as ready for review April 22, 2026 18:08
Copy link
Copy Markdown
Collaborator

@harbournick harbournick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@harbournick harbournick merged commit 84aa0e4 into main Apr 22, 2026
63 checks passed
@harbournick harbournick deleted the artem/SD-2652 branch April 22, 2026 21:27
@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented Apr 22, 2026

🎉 This PR is included in vscode-ext v2.3.0-next.44

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented Apr 22, 2026

🎉 This PR is included in @superdoc-dev/react v1.2.0-next.42

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented Apr 22, 2026

🎉 This PR is included in template-builder v1.6.0-next.7

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented Apr 22, 2026

🎉 This PR is included in esign v2.3.0-next.44

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented Apr 22, 2026

🎉 This PR is included in superdoc v1.28.0-next.7

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented Apr 22, 2026

🎉 This PR is included in superdoc-cli v0.8.0-next.7

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented Apr 22, 2026

🎉 This PR is included in superdoc-sdk v1.6.0-next.43

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants