Release note · August 1, 2026

The marker behind Word's embedded OLE objects

By SybilGambleyyu · DocFence 0.27.0

An embedded-object relationship or payload answers one useful question: what package material is present. It does not by itself say whether a Word story stores the legacy Office VML marker that identifies an embedded OLE object. The converse is also true: a marker is not proof that a client will open, activate, render, or trust an object.

DocFence 0.27 adds a narrow, privacy-safe inventory for that marker: Office VML o:OLEObject with an unqualified Type="Embed". It gives document CI a stable stored-markup signal without uploading package material or pretending a parser can forecast Word runtime behavior.

A direct marker, not a rendering model

The Open XML SDK documents o:OLEObject as Office VML markup for an embedded OLE object. The ECMA-376 element definition identifies its optional r:id, Type, program, shape, object, field-code, and update metadata. The element can occur through several parent forms, so DocFence follows the direct stored marker in supported Word stories rather than assigning it one rendered-object position.

Every matching marker is retained as stored evidence, including duplicates and markers inside Markup Compatibility branches. The boundary is intentionally separate from Type="Link", WordprocessingML w:objectEmbed and w:objectLink, VML image and shape links, fields, and generic embedded OLE/package/control relationship and payload totals. It neither selects a branch nor associates the marker with a visible shape.

Relationship evidence without opening an object

When a marker has r:id, DocFence classifies a standard OLE-object relationship by its stored internal or external target mode. Any other resolved type or mode remains visible as unsupported evidence, and an optional-ID marker without r:id has its own class. The OOXML Embedded Object Part contract permits standard OLE-object relationships with either stored target mode.

UpdateMode is deliberately absent from the public embedded-object inventory. The standard describes that setting for the Link form, not as embedded-object behavior. DocFence retains the complete direct marker only in a private fingerprint, so a same-count program, field-code, update-metadata, or target rewrite remains review-visible while relationship-ID renumbering with unchanged semantics stays quiet.

Private semantics, concrete gates

JSON, Markdown, and SARIF expose aggregate marker/story and relationship-classification counts only. Program, shape, object, relationship, target, update, field-code, XML, story-path, and fingerprint data remains private.

A handoff that must carry no direct VML embedded-OLE marker can state that policy directly:

rules:
  require_no_word_vml_embedded_ole_objects: true

That candidate-state gate emits DFP067. A controlled template that deliberately retains approved markers can protect its private baseline instead:

rules:
  no_word_vml_embedded_ole_object_changes: true

DFP068 detects a material private-inventory change. The two gates complement, rather than replace, the generic embedded-object checks for orphaned relationships and payloads.

Real package evidence, bounded claims

The installed release profiles the Open XML SDK's public ole.docx fixture as one direct embedded marker with an internal standard OLE-object relationship and payload. It reports the same aggregate contract for each of five public docx4j OLE fixtures.

The corpus coverage is deliberately stated, not generalized: a pinned scan found direct markers in 22 of 503 readable Open XML SDK package candidates (two of 505 candidates produced read errors) and five of 141 docx4j Word packages. Those public test assets demonstrate real serialized forms and give regression fixtures; they are not a prevalence survey, a payload-safety assessment, or a client-interoperability claim.

The 53-test release suite covers external/internal/unsupported/missing-ID classes, duplicate and linked-marker separation, body/header stories, Transitional and Strict namespaces, orphan exclusion, unavailable relationships, same-count program/update/target rewrites, relationship-ID stability, privacy redaction, and JSON/Markdown/SARIF policy output. Hosted CI passed on Python 3.11 and 3.13 for both the release commit and tag. Independently rebuilt tagged artifacts matched byte-for-byte; fresh public downloads passed checksum verification, and an isolated installed wheel profiled the public Open XML SDK fixture with the expected aggregate contract.

DocFence does not select a Markup Compatibility branch, retrieve a target, open or activate an OLE object, decode its payload, render it, or execute it. It does not establish that Word will associate a marker with a visible shape or honor it. Use it as a bounded local review signal alongside rendering, security, and domain-specific review.

python -m pip install https://github.com/SybilGambleyyu/docfence/releases/download/v0.27.0/docfence-0.27.0-py3-none-any.whl

docfence profile candidate.docx --format markdown
docfence check approved.docx candidate.docx --policy docfence.yml --format sarif --output docfence.sarif

The public release includes the wheel, source archive, and SHA-256 manifest. The tagged policy reference, threat model, and validation notes define the exact behavior, privacy contract, and limits.