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; } } }