fix: Squirrel.Mac crash when zip extraction fails (#47271)

* fix: Squirrel.Mac crash when zip extraction process fails to launch

* chore: add end-to-end test
This commit is contained in:
Niklas Wenzel
2025-05-29 19:31:46 +02:00
committed by GitHub
parent 5b5f900e34
commit 4e61f5b26f
4 changed files with 81 additions and 0 deletions

View File

@@ -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',

View File

@@ -0,0 +1,5 @@
(version 1)
(allow default)
(deny process-exec
(literal "/usr/bin/ditto")
)