Skip to content

feat: asar integrity digest#1890

Open
erickzhao wants to merge 5 commits intomainfrom
feat/asar-integrity-digest
Open

feat: asar integrity digest#1890
erickzhao wants to merge 5 commits intomainfrom
feat/asar-integrity-digest

Conversation

@erickzhao
Copy link
Copy Markdown
Member

@erickzhao erickzhao commented Mar 30, 2026

Description

This PR implements the logic from electron/asar#380 and electron/forge#4159 directly into the Packager pipeline.

The pivot to implementing this logic in @electron/packager means that we get to extend the existing AsarIntegrity handling logic and provide a zero-config way of implementing the integrity digest for consumers. Packager and Forge users will need to just bump up the version of Packager they're consuming to get this feature.

For more details, see the original Electron PR: electron/electron#48587.

@erickzhao erickzhao force-pushed the feat/asar-integrity-digest branch 2 times, most recently from 99dcc60 to 9700342 Compare March 30, 2026 23:47
Co-authored-by: Noah Gregory <noahmgregory@gmail.com>
@erickzhao erickzhao force-pushed the feat/asar-integrity-digest branch from 9700342 to 24441f3 Compare March 30, 2026 23:48
@erickzhao erickzhao marked this pull request as ready for review March 31, 2026 19:50
@erickzhao erickzhao requested a review from a team as a code owner March 31, 2026 19:50
MarshallOfSound and others added 4 commits March 31, 2026 16:25
The "does not write digest when asar is disabled" test wrapped its
only assertion in `if (sentinelIndex !== -1)`, silently passing with
zero assertions if the sentinel was missing. Both sibling tests in the
same describe block explicitly assert the sentinel exists — this one
drifted. With test/config.json on 41.1.0 the sentinel is guaranteed
present, so the guard only masked failures.
Previously setIntegrityDigest loaded the entire Electron Framework
binary (150-500 MB) into memory, scanned it, modified 34 bytes, and
wrote the whole thing back. Now it scans in 4 MB chunks with two
concurrent workers (I/O overlaps Buffer.indexOf CPU) and patches only
the 34-byte digest slot(s) via handle.write at the found position(s).
Each chunk overreads sentinel.length-1 bytes so a sentinel straddling
a boundary is still detected. Peak memory drops from ~binary-size to
~8 MB. Same approach as electron/fuses#96, which benched 10-15x faster
on 150-300 MB binaries.

Adds two synthetic-binary tests: one plants the sentinel across a 4 MB
boundary (verified load-bearing via mutation), one plants a sentinel in
each of two chunks to cover the universal-binary multi-write path. Both
skip packager() and run in ~10ms.
setIntegrityDigest had grown to ~155 lines after the chunked-scan
change. Pull the scan/validate/write block out to a module-level
helper alongside isAsarIntegrity; the method now just gates on
version, resolves integrity, computes the hash, and calls through.
Sentinel is passed as a parameter rather than referenced via
MacApp.INTEGRITY_DIGEST_SENTINEL to avoid a no-use-before-define
disable comment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants