From b262b7718bda7a39cb8e945e3d29bf41e1a381cb Mon Sep 17 00:00:00 2001 From: John Stevenson Date: Fri, 21 Jan 2022 08:48:41 +0000 Subject: [PATCH] Use copy in selfupdate to fix Windows PHP-8.1 regression (#10446) --- src/Composer/Command/SelfUpdateCommand.php | 29 +++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/Composer/Command/SelfUpdateCommand.php b/src/Composer/Command/SelfUpdateCommand.php index 686a48b02..99f8f4ec6 100644 --- a/src/Composer/Command/SelfUpdateCommand.php +++ b/src/Composer/Command/SelfUpdateCommand.php @@ -104,7 +104,9 @@ EOT $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0]; if ($input->getOption('update-keys')) { - return $this->fetchKeys($io, $config); + $this->fetchKeys($io, $config); + + return 0; } // ensure composer.phar location is accessible @@ -417,7 +419,14 @@ TAGSPUBKEY } try { - rename($newFilename, $localFilename); + if (Platform::isWindows()) { + // use copy to apply permissions from the destination directory + // as rename uses source permissions and may block other users + copy($newFilename, $localFilename); + @unlink($newFilename); + } else { + rename($newFilename, $localFilename); + } return true; } catch (\Exception $e) { @@ -428,6 +437,7 @@ TAGSPUBKEY return $this->tryAsWindowsAdmin($localFilename, $newFilename); } + @unlink($newFilename); $action = 'Composer '.($backupTarget ? 'update' : 'rollback'); throw new FilesystemException($action.' failed: "'.$localFilename.'" could not be written.'.PHP_EOL.$e->getMessage()); } @@ -528,7 +538,7 @@ TAGSPUBKEY /** * Invokes a UAC prompt to update composer.phar as an admin * - * Uses a .vbs script to elevate and run the cmd.exe move command. + * Uses a .vbs script to elevate and run the cmd.exe copy command. * * @param string $localFilename The composer.phar location * @param string $newFilename The downloaded or backup phar @@ -554,13 +564,13 @@ TAGSPUBKEY $checksum = hash_file('sha256', $newFilename); - // cmd's internal move is fussy about backslashes + // cmd's internal copy is fussy about backslashes $source = str_replace('/', '\\', $newFilename); $destination = str_replace('/', '\\', $localFilename); $vbs = <<writeError('Operation succeeded.'); + @unlink($newFilename); } else { - $io->writeError('Operation failed (file not written). '.$helpMessage.''); - }; + $io->writeError('Operation failed.'.$helpMessage.''); + } return $result; }