vendor-libreoffice-20260822 (headless LibreOffice, macOS arm64, r3)
Prebuilt, privacy-scrubbed headless LibreOffice engine for macOS arm64 — vendored dependency for
the Norma app, not an app release itself (--latest=false; does not affect the app's release
lineage or its Sparkle appcast).
What this is
A native macOS arm64 build of LibreOffice/core @ 11482c8f71bc76ed6260bc03b1576a52a788ab4f
with --enable-headless (the svp/headless VCL backend — the same shape LibreOffice's own iOS
port uses). Same commit, same configure flags, same build as -r2 — this asset changes only the
two items below. Zero source patches anywhere in this build.
Why -r3
Two disclosed changes on top of -r2, both from the same already-built core/instdir/ (no
rebuild):
-
The OOXML export fix.
-r2'ssaveAsto.xlsxcrashed the whole helper process —
libuno_sal.dylib.3's text-encoding subsystem lazilydlopenslibsal_textenclo.dylibby
name the first time a full charset lookup is needed (e.g. an Excel font record's Windows
charset ID), andabort()s when the load fails. That dylib is absent from-r2's 66-dylib
Frameworks/because it is reached only through a runtimedlopen, never a link-time
dependency —-r2's closure recipe (aDYLD_PRINT_LIBRARIEStrace of an import+paint-only
workload, plus a one-levelotool -Lsafety net) had no way to see it.-r3adds this one
file — a verbatimcp -pPfrom the identicalinstdirevery other dylib already came from,
re-scanned for privacy independently, not assumed clean by inheritance. Verified before
packaging (a standalone LOK harness,product-set+ this one dylib, nothing else changed):
gate.xlsxnow saves successfully (real output file, clean exit);gate.pptxis unaffected
(already worked, still works).gate.docxstill does not save — the missing-dylib abort is
gone (no crash, reproduced on two independent fresh profiles), but a different, still-open
Writer/OOXML-export defect surfaces instead: a clean, caughtSVSTREAM_WRITE_ERROR
(ERRCODE_IO_CANTWRITE) insideSfxBaseModel::impl_store. Unrelated to the charset-table gap
this asset fixes; disclosed, not chased further here. -
A tar-container privacy fix
-r2didn't have. Measured directly against the live,
currently-published-r2asset (cold-downloaded, SHA-256-matched to its pin): the tarball's own
per-entry headers record the packaging account's macOS username and primary group, via
bsdtar's default owner-name recording — independent of, and not caught by,-r2's own
file-content byte-scan (which read extracted file bytes, never the tar's own header bytes).
-r3's tar is built with explicit owner/group suppression (tar --uid 0 --gid 0 --uname '' --gname ''); see the Privacy scan section below for the verification. The live-r2asset was
not modified or re-uploaded — a GitHub release asset is maintainer-replaceable at the same
URL, and re-publishing scrubbed bytes under the same name is exactly the silent-swap hazard this
repo's ownfetch-libreoffice.tsheader warns against. Flagged here as an open item for whoever
owns this asset's lifecycle to consider once-r3is the pinned, fetched asset.
Engine-wise, nothing else changed: all six format fixtures render pixel-identical (raw SHA-256 of
the paintTile output) to -r2/the original build. Adding one dylib and fixing tar metadata
changes zero pixels.
Contents
product-set/— the runtime closure:Frameworks/(67 of 248 possible dylibs —-r2's trim
plus this release's one added file) +Resources/(LibreOffice's config/UI-resource tree,
shipped whole, unchanged from-r2).LICENSES/— per-upstream-project license texts, plusMANIFEST.md(updated: 67 dylibs, the
new file is the same already-coveredlibreoffice-coremodule/license, no new upstream
project).VERSION-PIN— the exact configure flags, commit, build facts an embedder needs, the R3
ADDENDUM documenting both changes above in full (including the verified install-name/link shape
of the added dylib — matches its siblings, no patching needed), and the six-fixture pixel-hash
pins (unchanged from-r2).
Using this
Ships adhoc/linker-signed, as LibreOffice's own build produces it — this tarball does not sign
or notarize anything. An embedding application is responsible for re-signing these dylibs with its
own Developer ID identity (and hardened runtime, if applicable) at its own build time — Norma's own
embed phase does this, counting Mach-Os dynamically rather than assuming a fixed number, so the
67th dylib needs no build-script change.
See VERSION-PIN inside the archive for the dlopen entry point, the required _Exit(0) teardown
pattern, and the fontconfig caveat — all unchanged from -r2.
Privacy scan — exact command and full result
Reused this repo's own local-only identity guard (the same mechanism scripts/release.ts's §11b
publish gate uses for app releases) — ~/norma-private/git-hooks/name-guard.sh artifacts <path>,
patterns not reproduced here since this file ships inside a public release (the guard is deliberately
local-only, outside every repository, for exactly that reason).
Scanned separately, before compression:
- The added dylib alone (
libsal_textenclo.dylib): clean. product-set/Frameworks/whole (all 67 dylibs): clean.product-set/Resources/minus one already-known, byte-verified-unchanged-from--r2file
(liblangtag/language-subtag-registry.xml, IANA's language-subtag registry — a natural-language
collision,<description>Como Karim</description>, a real registered language name (ISO 639-3
cfg), not an identity leak; this exact file is already a standing exclusion in this repo's own
release-lib.tsNAME_SCAN_EXCLUSIONSfor the identical reason): clean.LICENSES/: clean.VERSION-PIN: clean.- The final, uncompressed
.tar(owner-suppressed): exactly one hit, independently verified
byte-for-byte to be the same IANA registry collision above (single match, same description
string, same file) — not a new leak, not identity-bearing. - The
.tar.zstwas verified by decompression round-trip (SHA-256-identical to the already-scanned
.tar), not re-scanned directly — compression would hide any string from a byte scan the same
way it would for a.zip/.dmg, so the meaningful gate is the uncompressed archive.
Zero identity hits anywhere in this asset.