Skip to content

Far future: a pure-Python OLE compound file layer — read, manipulate and write #129

Description

@toxicphreAK

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:

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.

Prerequisites before this is worth starting

  1. Expose the VBA project as bytes — read, transplant and strip macros #127 and Read and decompress VBA module source, behind an optional [vba] extra #128 landed, so there is a reader to test the writer against.
  2. A real macro fixture exists (see Read and decompress VBA module source, behind an optional [vba] extra #128 — the current one is a 27-byte stub).
  3. A decision on whether the CFB layer lives here or as a separate package.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions