From 1dc2c93261e7606d13e905d92deebb2c9cec7d7b Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 4 Mar 2024 14:39:30 +0100 Subject: [PATCH] Fix ensureDirectoryExists not working when a broken symlink appears somewhere in the path, fixes #11864 --- src/Composer/Util/Filesystem.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Composer/Util/Filesystem.php b/src/Composer/Util/Filesystem.php index 7ddcfa69f..baa3dfa8d 100644 --- a/src/Composer/Util/Filesystem.php +++ b/src/Composer/Util/Filesystem.php @@ -257,7 +257,21 @@ class Filesystem } if (!@mkdir($directory, 0777, true)) { - throw new \RuntimeException($directory.' does not exist and could not be created: '.(error_get_last()['message'] ?? '')); + $e = new \RuntimeException($directory.' does not exist and could not be created: '.(error_get_last()['message'] ?? '')); + + // in pathological cases with paths like path/to/broken-symlink/../foo is_dir will fail to detect path/to/foo + // but normalizing the ../ away first makes it work so we attempt this just in case, and if it still fails we + // report the initial error we had with the original path, and ignore the normalized path exception + // see https://github.com/composer/composer/issues/11864 + $normalized = $this->normalizePath($directory); + if ($normalized !== $directory) { + try { + $this->ensureDirectoryExists($normalized); + return; + } catch (\Throwable $ignoredEx) {} + } + + throw $e; } } }