From 72ad0733e2d0324a243fcecb6457f2a991196377 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Thu, 15 Sep 2022 12:34:11 +0200 Subject: [PATCH] Fix handling of multi-step upgrades that need to happen in lock-step Consider the following situation: - Package com.example.foo is installed in version 1.0.0. - Version 1.0.1 can be upgraded from 1.0.0. - Version 1.0.2 can be upgraded from 1.0.1 and adds a dependency on com.woltlab.bar which is not yet installed. - Version 1.0.3 can be upgraded from 1.0.2. Now the PackageinstallationScheduler will build the following plan when it's desired to upgrade com.woltlab.foo from 1.0.0 to 1.0.2: - Upgrade com.woltlab.foo to 1.0.1 - Install com.woltlab.bar to satisfy the dependencies for 1.0.2 - Upgrade com.woltlab.foo to 1.0.2 - Upgrade com.woltlab.foo to 1.0.3 Now when build the nodes for this plan, the upgrade instructions for 1.0.2 will not be detected, as the "previous package" logic used for iterative upgrades will set the previous package of com.woltlab.foo in 1.0.2 to com.woltlab.bar. Thus when upgrading to 1.0.2 the node builder will believe that com.woltlab.foo is installed in 1.0.0 when it actually is already upgraded to 1.0.1. Fix this by leveraging the $pendingPackages list which is already kept up to date for dependency resolution. --- .../system/package/PackageInstallationNodeBuilder.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php b/wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php index 589831f0e8..de9fca7311 100644 --- a/wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php +++ b/wcfsetup/install/files/lib/system/package/PackageInstallationNodeBuilder.class.php @@ -774,10 +774,10 @@ class PackageInstallationNodeBuilder $installation = new PackageInstallationDispatcher($queue); // work-around for iterative package updates - if ($this->installation->queue->action == 'update' && $queue->package == $this->installation->queue->package) { + if (isset(self::$pendingPackages[$queue->package])) { $installation->setPreviousPackage([ - 'package' => $this->installation->getArchive()->getPackageInfo('name'), - 'packageVersion' => $this->installation->getArchive()->getPackageInfo('version'), + 'package' => $queue->package, + 'packageVersion' => self::$pendingPackages[$queue->package], ]); } -- 2.20.1