fix: Squirrel.Mac crash when zip extraction fails (#47300)
* fix: Squirrel.Mac crash when zip extraction process fails to launch Co-authored-by: Niklas Wenzel <dev@nikwen.de> * chore: add end-to-end test Co-authored-by: Niklas Wenzel <dev@nikwen.de> --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Niklas Wenzel <dev@nikwen.de>
This commit is contained in:
parent
1487f5d8b4
commit
2a707ffbd8
4 changed files with 81 additions and 0 deletions
|
@ -7,3 +7,4 @@ fix_abort_installation_attempt_at_the_final_mile_if_the_app_is.patch
|
|||
feat_add_ability_to_prevent_version_downgrades.patch
|
||||
refactor_use_non-deprecated_nskeyedarchiver_apis.patch
|
||||
chore_turn_off_launchapplicationaturl_deprecation_errors_in_squirrel.patch
|
||||
fix_crash_when_process_to_extract_zip_cannot_be_launched.patch
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Niklas Wenzel <dev@nikwen.de>
|
||||
Date: Tue, 27 May 2025 02:03:54 +0200
|
||||
Subject: fix: crash when process to extract zip cannot be launched
|
||||
|
||||
Fixes https://github.com/electron/electron/issues/47270
|
||||
|
||||
diff --git a/Squirrel/SQRLZipArchiver.m b/Squirrel/SQRLZipArchiver.m
|
||||
index 68f5dac8e553638f41306956df9d38eeda18f8f2..a9cd676df63e19edf9e20473d27b85591c7cb49e 100644
|
||||
--- a/Squirrel/SQRLZipArchiver.m
|
||||
+++ b/Squirrel/SQRLZipArchiver.m
|
||||
@@ -153,7 +153,17 @@ - (RACSignal *)launchWithArguments:(NSArray *)arguments {
|
||||
setNameWithFormat:@"-launchWithArguments: %@", arguments];
|
||||
|
||||
self.dittoTask.arguments = arguments;
|
||||
- [self.dittoTask launch];
|
||||
+
|
||||
+ NSError *launchError = nil;
|
||||
+
|
||||
+ if (![self.dittoTask launchAndReturnError:&launchError]) {
|
||||
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
+ userInfo[NSLocalizedDescriptionKey] = launchError.localizedDescription;
|
||||
+
|
||||
+ NSLog(@"Starting ditto task failed with error: %@", launchError.localizedDescription);
|
||||
+
|
||||
+ return [RACSignal error:[NSError errorWithDomain:SQRLZipArchiverErrorDomain code:SQRLZipArchiverShellTaskFailed userInfo:userInfo]];
|
||||
+ }
|
||||
|
||||
return signal;
|
||||
}
|
|
@ -42,6 +42,16 @@ ifdescribe(shouldRunCodesignTests)('autoUpdater behavior', function () {
|
|||
return cp.spawn(path.resolve(appPath, 'Contents/MacOS/Electron'), args);
|
||||
};
|
||||
|
||||
const launchAppSandboxed = (appPath: string, profilePath: string, args: string[] = []) => {
|
||||
return spawn('/usr/bin/sandbox-exec', [
|
||||
'-f',
|
||||
profilePath,
|
||||
path.resolve(appPath, 'Contents/MacOS/Electron'),
|
||||
...args,
|
||||
'--no-sandbox'
|
||||
]);
|
||||
};
|
||||
|
||||
const getRunningShipIts = async (appPath: string) => {
|
||||
const processes = await psList();
|
||||
const activeShipIts = processes.filter(p => p.cmd?.includes('Squirrel.framework/Resources/ShipIt com.github.Electron.ShipIt') && p.cmd!.startsWith(appPath));
|
||||
|
@ -740,6 +750,41 @@ ifdescribe(shouldRunCodesignTests)('autoUpdater behavior', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should hit the download endpoint when an update is available and fail when the zip extraction process fails to launch', async () => {
|
||||
await withUpdatableApp({
|
||||
nextVersion: '2.0.0',
|
||||
startFixture: 'update',
|
||||
endFixture: 'update'
|
||||
}, async (appPath, updateZipPath) => {
|
||||
server.get('/update-file', (req, res) => {
|
||||
res.download(updateZipPath);
|
||||
});
|
||||
server.get('/update-check', (req, res) => {
|
||||
res.json({
|
||||
url: `http://localhost:${port}/update-file`,
|
||||
name: 'My Release Name',
|
||||
notes: 'Theses are some release notes innit',
|
||||
pub_date: (new Date()).toString()
|
||||
});
|
||||
});
|
||||
const launchResult = await launchAppSandboxed(
|
||||
appPath,
|
||||
path.resolve(__dirname, 'fixtures/auto-update/sandbox/block-ditto.sb'),
|
||||
[`http://localhost:${port}/update-check`]
|
||||
);
|
||||
logOnError(launchResult, () => {
|
||||
expect(launchResult).to.have.property('code', 1);
|
||||
expect(launchResult.out).to.include('Starting ditto task failed with error:');
|
||||
expect(launchResult.out).to.include('SQRLZipArchiverErrorDomain');
|
||||
expect(requests).to.have.lengthOf(2);
|
||||
expect(requests[0]).to.have.property('url', '/update-check');
|
||||
expect(requests[1]).to.have.property('url', '/update-file');
|
||||
expect(requests[0].header('user-agent')).to.include('Electron/');
|
||||
expect(requests[1].header('user-agent')).to.include('Electron/');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should hit the download endpoint when an update is available and update successfully when the zip is provided with JSON update mode', async () => {
|
||||
await withUpdatableApp({
|
||||
nextVersion: '2.0.0',
|
||||
|
|
5
spec/fixtures/auto-update/sandbox/block-ditto.sb
vendored
Normal file
5
spec/fixtures/auto-update/sandbox/block-ditto.sb
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
(version 1)
|
||||
(allow default)
|
||||
(deny process-exec
|
||||
(literal "/usr/bin/ditto")
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue