#47271: fix: Squirrel.Mac crash when zip extraction fails
Merged
Description of Change
Fixes #47270
Squirrel.Mac launches /usr/bin/ditto
to extract the update zip file. When that process fails to launch, the (deprecated) launch
function will raise an NSInvalidArgumentException
. This exception wasn't caught. Thus, the app crashed.
This PR migrates the code to the (non-deprecated) launchAndReturnError
function and adds proper error handling.
I've also included a test to prevent this from regressing.
This is the first Objective-C code I've ever written, so please be extra careful during your review.
I've tested the change as follows:
All autoUpdater tests pass (incl. the newly added test).
nikwen@MacBook spec % e test --no-remote -g "autoUpdater"
Running "/usr/local/bin/node ./script/spec-runner.js -g autoUpdater" in /Volumes/Electron/electron/src/electron
Triggering runners: main
Running: Main process specs
ok 1 autoUpdater module checkForUpdates emits an error on Windows if the feed URL is not set # SKIP -
ok 2 autoUpdater module getFeedURL returns an empty string by default
ok 3 autoUpdater module getFeedURL correctly fetches the previously set FeedURL # SKIP -
ok 4 autoUpdater module setFeedURL on Mac or Windows sets url successfully using old (url, headers) syntax
ok 5 autoUpdater module setFeedURL on Mac or Windows throws if no url is provided when using the old style
ok 6 autoUpdater module setFeedURL on Mac or Windows sets url successfully using new ({ url }) syntax
ok 7 autoUpdater module setFeedURL on Mac or Windows throws if no url is provided when using the new style
ok 8 autoUpdater module setFeedURL on Mac emits an error when the application is unsigned # SKIP -
ok 9 autoUpdater module setFeedURL on Mac does not throw if default is the serverType # SKIP -
ok 10 autoUpdater module setFeedURL on Mac does not throw if json is the serverType # SKIP -
ok 11 autoUpdater module setFeedURL on Mac does throw if an unknown string is the serverType # SKIP -
ok 12 autoUpdater module quitAndInstall emits an error on Windows when no update is available # SKIP -
ok 13 autoUpdater behavior should have a valid code signing identity
ok 14 autoUpdater behavior should fail to set the feed URL when the app is not signed # SKIP -
ok 15 autoUpdater behavior should cleanly set the feed URL when the app is signed
ok 16 autoUpdater behavior with update server should hit the update endpoint when checkForUpdates is called
ok 17 autoUpdater behavior with update server should hit the update endpoint with customer headers when checkForUpdates is called
ok 18 autoUpdater behavior with update server should hit the download endpoint when an update is available and error if the file is bad
ok 19 autoUpdater behavior with update server should hit the download endpoint when an update is available and update successfully when the zip is provided
ok 20 autoUpdater behavior with update server should hit the download endpoint when an update is available and update successfully when the zip is provided even after a different update was staged
ok 21 autoUpdater behavior with update server should update to lower version numbers
ok 22 autoUpdater behavior with update server should abort the update if the application is still running when ShipIt kicks off
ok 23 autoUpdater behavior with update server should hit the download endpoint when an update is available and fail when the zip signature is invalid
ok 24 autoUpdater behavior with update server should hit the download endpoint when an update is available and fail when the ShipIt binary is a symlink
ok 25 autoUpdater behavior with update server should hit the download endpoint when an update is available and fail when the Electron Framework is modified
ok 26 autoUpdater behavior with update server should hit the download endpoint when an update is available and fail when the zip extraction process fails to launch
ok 27 autoUpdater behavior with update server should hit the download endpoint when an update is available and update successfully when the zip is provided with JSON update mode
ok 28 autoUpdater behavior with update server should hit the download endpoint when an update is available and not update in JSON update mode when the currentRelease is older than the current version
ok 29 autoUpdater behavior with update server with ElectronSquirrelPreventDowngrades enabled should not update to lower version numbers
ok 30 autoUpdater behavior with update server with ElectronSquirrelPreventDowngrades enabled should not update to version strings that are not simple Major.Minor.Patch
ok 31 autoUpdater behavior with update server with ElectronSquirrelPreventDowngrades enabled should still update to higher version numbers
ok 32 autoUpdater behavior with update server with ElectronSquirrelPreventDowngrades enabled should compare version numbers correctly
ok 33 autoUpdater behavior with update server with SquirrelMacEnableDirectContentsWrite enabled should hit the download endpoint when an update is available and update successfully when the zip is provided leaving the parent directory untouched
# tests 25
# pass 25
# fail 0
1..33
[1755:0527/181855.901631:ERROR:base/process/kill_posix.cc:33] waitpid(1757): No child processes (10)
✓ Electron main process tests passed.
The newly added test crashes with SIGTRAP on main.
nikwen@MacBook spec % e test --no-remote -g "zip extraction process" --electronVersion 38.0.0-nightly.20250526
Running "/usr/local/bin/node ./script/spec-runner.js -g zip extraction process --electronVersion=38.0.0-nightly.20250526" in /Volumes/Electron/electron/src/electron
Only running: [ 'main' ]
Running against Electron undefined
Running: Main process specs
Unhandled exception in main spec runner: AssertionError: expected 'SIGTRAP' to equal null
at ChildProcess.<anonymous> (/Volumes/Electron/electron/src/electron/spec/lib/codesign-helpers.ts:72:25)
at ChildProcess.emit (node:events:518:28)
at Process.ChildProcess._handle.onexit (node:internal/child_process:293:12) {
showDiff: true,
actual: 'SIGTRAP',
expected: null,
operator: 'strictEqual'
}
not ok 1 autoUpdater behavior with update server should hit the download endpoint when an update is available and fail when the zip extraction process fails to launch
expected 'SIGTRAP' to equal null
AssertionError: expected 'SIGTRAP' to equal null
at ChildProcess.<anonymous> (electron/spec/lib/codesign-helpers.ts:72:25)
at ChildProcess.emit (node:events:518:28)
at Process.ChildProcess._handle.onexit (node:internal/child_process:293:12)
✗ Electron tests failed with code 1.
ERROR Error: Command failed: /usr/local/bin/node ./script/spec-runner.js -g zip extraction process --electronVersion=38.0.0-nightly.20250526
at genericNodeError (node:internal/errors:984:15)
at wrappedFn (node:internal/errors:538:14)
at checkExecSyncError (node:child_process:891:11)
at Object.execFileSync (node:child_process:927:15)
at runSpecRunner (/Users/nikwen/.electron_build_tools/src/e-test.js:33:16)
at Command.<anonymous> (/Users/nikwen/.electron_build_tools/src/e-test.js:76:7)
at Command.listener [as _actionHandler] (/Users/nikwen/.electron_build_tools/node_modules/commander/lib/command.js:480:17)
at /Users/nikwen/.electron_build_tools/node_modules/commander/lib/command.js:1234:65
at Command._chainOrCall (/Users/nikwen/.electron_build_tools/node_modules/commander/lib/command.js:1151:12)
at Command._parseCommand (/Users/nikwen/.electron_build_tools/node_modules/commander/lib/command.js:1234:27)
Checklist
- PR description included and stakeholders cc'd
-
npm test
passes - tests are changed or added
- PR release notes describe the change in a way relevant to app developers, and are capitalized, punctuated, and past tense.
Release Notes
Notes: Fixed crash in autoUpdater
on macOS when zip extraction failed.
Backports
Semver Impact
Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.
Semantic Versioning helps users understand the impact of updates:
- Major (X.y.z): Breaking changes that may require code modifications
- Minor (x.Y.z): New features that maintain backward compatibility
- Patch (x.y.Z): Bug fixes that don't change the API
- None: Changes that don't affect using facing parts of Electron