Move a lot of the installation work to be done during the first phase of installation (when possible), before the target app needs to be terminated. For the common case where the old and new bundles are on the same volume, the final phase of installation requiring a restart is now just an atomic swap.
Also move the termination listener to the agent app which resolves some launch/CI failures we've been seeing.
Minimum OS preprocessor checks should only be used when compiler may generate compile warnings for deprecated APIs when the deployment target is raised.
If the app termination request is delayed or canceled, the user can check for updates again with the standard user driver and try installing/relaunching again, which will trigger the installer to send another quit event to the running application.
Before the install/relaunch window would close but the check for updates option would still be present but not functional.
Wait for appcast item registration before finishing automatic update driver.
This fixes a potential race issue where sometimes the automatic update driver on completion would sometimes not trigger to prompt an update alert immediately for critical updates. Note in this case, the update would still be installed on app termination and would still be scheduled to alert the user on the regular update check interval, so this issue is not severe.
We fix one memory leak when calculating sha's, one memory leak in the xar delta applying path, and avoid creating Bundles for reading the Sparkle framework version.
There are some other small leaks with the xar delta creation/applying code but since it's a legacy implementation and the APIs are undocumented I don't want to touch it too much.
The biggest culprit here is the leak when calculating sha's I believe, if you have many archive items.
For creation, we will disallow creating delta updates if a custom resource fork icon data is found in either the old or app bundles.
For applying, we will just ignore the icon data when performing hash verification and continue applying the patch.
The update code uses the compareFiles function to determine the sort order of file names in a directory, which is then compared with a list of files in the Sparkle update info. If the list of files of a directory from Sparkle's update is different than what is on disk, the Sparkle abandons the update and does a full download. This bug would prevent Sparkle from updating properly when the file lists are calculated on an English language system, but then checked on a destination Japanese system.
The fix is to use strcoll_l(), which is locale-independent, when comparing file names for sorting. This will ignore any locale changes the host application has made that could potentially affect Sparkle's sort order.
In generate_appcast we:
* Validate code signing integrity of new updates
* Add hidden flag to disable checking for nested code during validation
* Warn if new and old apps have differing signing identities when generating deltas
* Only track 0755 permissions for symbolic links
Also warn the user when encountering symbolic links that have a non-standard permission mode.
* Warn users when bad or irregular permissions are encountered
We have one heuristic for when a .framework version changes, and another for when a file with the same name moves to another location.
To support this, we added a clone + binary diff command.
Also document and improve the format.
This new format introduces:
* A new container format which stores metadata in a way that is more efficient for compression, decompression, and size. Creation time can be 2x faster, apply time can be a few seconds faster, size savings can be 500 KB - couple of MB due to metadata alone.
* An array of supported compression formats including lzma, bzip2, zlib and more. We now default to lzma which is as competitive as bzip2 (which we were using in version 2 format) in applying/creation times, but can save several MB on size.
* Tracking of files from an old app being replicated in different locations in the new app. This can track unchanged files being renamed and can result in significant savings if the files are large.
Version 2 format is still the default. To use version 3, pass --version=3 to BinaryDelta when creating a patch. We will switch the default to version 3 later. generate_appcast support is upcoming.