From 119c4d91f3f5ee992df27da84d047b9ff69852a3 Mon Sep 17 00:00:00 2001 From: Helmut Hummel <typo3@helhum.io> Date: Thu, 7 Sep 2023 11:51:52 +0200 Subject: [PATCH] [BUGFIX] Do not try to create symlinks on Windows When a junction already exists on Windows, it is tried to create a symlink, because of a missing OS check. While this works as errors are ignored, it is an unnecessary filesystem call. Therefore the code is changed to only emit the appropriate filesystem operations per OS. Resolves: #101871 Related: #98434 Related: #98447 Releases: main, 12.4, 11.5 Change-Id: Ifafadceae3742da23fd1a40e5aab50074e60313c Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/80904 Tested-by: core-ci <typo3@b13.com> Tested-by: Benjamin Franzke <ben@bnf.dev> Reviewed-by: Benjamin Franzke <ben@bnf.dev> --- .../Composer/PackageArtifactBuilder.php | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php b/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php index 88f32614ff3c..cd7318b2f472 100644 --- a/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php +++ b/typo3/sysext/core/Classes/Composer/PackageArtifactBuilder.php @@ -275,11 +275,31 @@ class PackageArtifactBuilder extends PackageManager implements InstallerScript [$relativePrefix] = explode('Resources/Public', $relativePath); $publicResourcesPath = $this->fileSystem->normalizePath($this->config->get('web-dir') . '/_assets/' . md5($relativePrefix)); $this->fileSystem->ensureDirectoryExists(dirname($publicResourcesPath)); - if (Platform::isWindows() && !$this->fileSystem->isJunction($publicResourcesPath)) { - $this->fileSystem->junction($fileSystemResourcesPath, $publicResourcesPath); - } elseif (!$this->fileSystem->isSymlinkedDirectory($publicResourcesPath)) { - $this->fileSystem->relativeSymlink($fileSystemResourcesPath, $publicResourcesPath); + if (Platform::isWindows()) { + $this->ensureJunctionExists($fileSystemResourcesPath, $publicResourcesPath); + } else { + $this->ensureSymlinkExists($fileSystemResourcesPath, $publicResourcesPath); } } } + + private function ensureJunctionExists(string $target, string $junction): void + { + if (!$this->fileSystem->isJunction($junction)) { + // Cleanup a possible symlink that might have been installed by ourselves prior to #98434 + // Note: Unprivileged deletion of symlinks is allowed, even if they were created by a + // privileged user + if (is_link($junction)) { + $this->fileSystem->unlink($junction); + } + $this->fileSystem->junction($target, $junction); + } + } + + private function ensureSymlinkExists(string $target, string $link): void + { + if (!$this->fileSystem->isSymlinkedDirectory($link)) { + $this->fileSystem->relativeSymlink($target, $link); + } + } } -- GitLab