Conversation
… (SD-2888) xml-js's js2xml does not re-escape &, <, > in attribute values, so a hyperlink Target containing & was decoded on parse and written back as a bare & during rels reconciliation. The malformed word/_rels/document.xml.rels caused Word to show an "unreadable content" repair prompt and apply default formatting (font, table widths, line spacing) on top of the otherwise-correct document. Adds a serializeOpcXml helper that escapes attribute values via attributeValueFn (using a placeholder pivot to avoid double-escaping the " xml-js pre-injects), and routes both reconcile-document-relationships and sync-package-metadata through it. The latter closes the same latent bug for _rels/.rels and [Content_Types].xml.
45ba9da to
db110d3
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Word-authored .docx with `&` in a hyperlink Target now exercised through zero-edit export. Catches the bare-`&` malformed-rels regression at the integration level; existing unit tests cover the OPC helper directly.
caio-pizzol
left a comment
There was a problem hiding this comment.
hey @tupizz! good call centralizing this in serializeOpcXml :)
i pushed a behavior test that exercises the export path against a Word-authored fixture - catches the bare-& regression at the integration level (the unit tests cover the helper directly).
lgtm.
|
🎉 This PR is included in @superdoc-dev/mcp v0.3.0-next.63 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.2.0-next.105 The release is available on GitHub release |
|
🎉 This PR is included in superdoc-cli v0.8.0-next.79 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.3.0-next.107 |
|
🎉 This PR is included in superdoc v1.30.0-next.61 The release is available on GitHub release |
|
🎉 This PR is included in superdoc-sdk v1.8.0-next.61 |
|
🎉 This PR is included in superdoc-cli v0.9.0 The release is available on GitHub release |
|
🎉 This PR is included in superdoc v1.32.0 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/mcp v0.4.0 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.3.0 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.4.0 |
Summary
&inword/_rels/document.xml.relsthat caused Word to show "unreadable content" on opening exported DOCX files. Linear: SD-2888serializeOpcXmlhelper that escapes&,<,>in OPC attribute values soxml-js'sjs2xmlround-trips entities correctlyreconcile-document-relationshipsandsync-package-metadatathrough it (closes the same latent bug for_rels/.relsand[Content_Types].xml)Root cause
xml-js'sxml2jsdecodes&→&in attribute values;js2xmldoes not re-escape on output. WhenreconcileDocumentRelationshipsrewritesword/_rels/document.xml.rels(e.g. to add the managednumberingrelationship), every existing hyperlinkTargetcontaining&is emitted with a bare&, producing malformed XML. Word's repair-on-open then applies default fonts (Times New Roman → Aptos), table cell widths, and paragraph spacing, which look like unrelated regressions but are downstream effects of the same root cause.The trick in the helper:
xml-jscallsattributeValueFnwith the value after pre-escaping"to". A naïve&→&would double-escape that token. The helper pivots"through a placeholder, escapes&/</>, then restores".Files changed
packages/super-editor/src/editors/v1/core/opc/xml-serialization.js(helper)packages/super-editor/src/editors/v1/core/opc/xml-serialization.test.js(5 unit tests)reconcile-document-relationships.js— call site swapreconcile-document-relationships.test.js— 2 SD-2888 regression testssync-package-metadata.js— call site swapTest plan
pnpm --filter super-editor test(all 12,367 tests pass; 7 new)npx vitest run src/editors/v1/core/opc(43/43 pass)editor.exportDocx()→ unzip → verifyword/_rels/document.xml.relscontains&companyId(3×, matching rId8/9/10 in the bug) and zero bare&companyId