You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Split out of #27, tier 3 of three. Far future and explicitly optional — filed as a plan to build on rather than as scheduled work.
The narrow ask in #27 was "writing OLE objects to create some VBA content from nowhere". The general capability underneath it is more interesting than the VBA case alone: reading, manipulating and writing OLE compound files from Python.
Why the general version is the right framing
Three separate things in this codebase want the same layer, and each of them currently stops at the container boundary:
Support embedded OLE objects (w:object) #101 — embedded OLE objects (w:object). An embedded spreadsheet or PDF under word/embeddings/ is a compound file. Reading its contents, or generating one, needs exactly this.
opc/phys_pkg.py:46 already sniffs the OLE signature to tell the user their document is password-protected. That is the whole of our current OLE awareness: eight bytes.
A compound-file layer serves all three. Building it for VBA alone would be building it for one caller.
The state of the art in Python
There is no maintained pure-Python OLE compound-file writer. olefile is read-only and says so. pyolecf is a binding and also read-oriented. The formats are documented — [MS-CFB] for the container, [MS-OVBA] for the VBA project inside it — so this is implementable, but it is implementing a filesystem: FAT and mini-FAT sector allocation chains, a directory red-black tree, stream resizing, and the mini-stream cutoff at 4096 bytes. It is a genuinely interesting piece of work and a genuinely large one.
That gap is also the argument for doing it: a well-tested pure-Python CFB reader/writer would be independently useful, and arguably wants to be its own package rather than a module inside a .docx library. Worth deciding that up front — if it ships separately, this repo depends on it as an optional extra and the scope question resolves itself.
The failure mode to respect
A compound file with subtly wrong allocation chains does not error. Word opens it, decides the document is damaged, and silently repairs it — discarding the macros. Any implementation needs round-trip tests against Word-authored files and a validator, not just "it parses".
Cheaper substitutes, which is why this is not scheduled
Nearly every concrete use case for "generate VBA" is served by the donor-file approach in #127: author the project once in Word, ship the vbaProject.bin, drop it into generated documents. That covers corporate template pipelines, which is the realistic demand. This issue is for the case where that is genuinely not enough — synthesising or editing project contents programmatically.
One consideration to record
Programmatic macro generation is dual-use. There are legitimate uses — build automation, template pipelines — and it also lowers the bar for producing weaponised documents. Not a reason to refuse the work, but it is a reason to keep it behind an optional extra rather than in the default install, and a reason the donor-file route in #127 is the better default answer for most callers.
Split out of #27, tier 3 of three. Far future and explicitly optional — filed as a plan to build on rather than as scheduled work.
The narrow ask in #27 was "writing OLE objects to create some VBA content from nowhere". The general capability underneath it is more interesting than the VBA case alone: reading, manipulating and writing OLE compound files from Python.
Why the general version is the right framing
Three separate things in this codebase want the same layer, and each of them currently stops at the container boundary:
[vba]extra #128 reads a VBA project but cannot write one back. Editing a module's source means rewriting the compound file.w:object). An embedded spreadsheet or PDF underword/embeddings/is a compound file. Reading its contents, or generating one, needs exactly this.opc/phys_pkg.py:46already sniffs the OLE signature to tell the user their document is password-protected. That is the whole of our current OLE awareness: eight bytes.A compound-file layer serves all three. Building it for VBA alone would be building it for one caller.
The state of the art in Python
There is no maintained pure-Python OLE compound-file writer.
olefileis read-only and says so.pyolecfis a binding and also read-oriented. The formats are documented — [MS-CFB] for the container, [MS-OVBA] for the VBA project inside it — so this is implementable, but it is implementing a filesystem: FAT and mini-FAT sector allocation chains, a directory red-black tree, stream resizing, and the mini-stream cutoff at 4096 bytes. It is a genuinely interesting piece of work and a genuinely large one.That gap is also the argument for doing it: a well-tested pure-Python CFB reader/writer would be independently useful, and arguably wants to be its own package rather than a module inside a
.docxlibrary. Worth deciding that up front — if it ships separately, this repo depends on it as an optional extra and the scope question resolves itself.The failure mode to respect
A compound file with subtly wrong allocation chains does not error. Word opens it, decides the document is damaged, and silently repairs it — discarding the macros. Any implementation needs round-trip tests against Word-authored files and a validator, not just "it parses".
Cheaper substitutes, which is why this is not scheduled
Nearly every concrete use case for "generate VBA" is served by the donor-file approach in #127: author the project once in Word, ship the
vbaProject.bin, drop it into generated documents. That covers corporate template pipelines, which is the realistic demand. This issue is for the case where that is genuinely not enough — synthesising or editing project contents programmatically.One consideration to record
Programmatic macro generation is dual-use. There are legitimate uses — build automation, template pipelines — and it also lowers the bar for producing weaponised documents. Not a reason to refuse the work, but it is a reason to keep it behind an optional extra rather than in the default install, and a reason the donor-file route in #127 is the better default answer for most callers.
Prerequisites before this is worth starting
[vba]extra #128 landed, so there is a reader to test the writer against.[vba]extra #128 — the current one is a 27-byte stub).