From 3e727850ffd1cdec4acdd483824b65c645c84d57 Mon Sep 17 00:00:00 2001 From: hakre Date: Thu, 24 Jul 2014 15:08:25 +0200 Subject: [PATCH] unlinking symlinked directories and trailing slashes Filesystem::removeDirectory() didn't detect all symlinked directories properly due to not resolving pathnames with trailing slashes first. this commit fixes that issue by resolving pathnames with trailing slashes by removing those in case they are representing a symlinked directory. #3144 Reference: A.4.12 Pathname Resolution - The Open Group Base Specifications Issue 7 IEEE Std 1003.1, 2013 Edition Section --- src/Composer/Util/Filesystem.php | 49 ++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/Composer/Util/Filesystem.php b/src/Composer/Util/Filesystem.php index 7cc463525..5104caaec 100644 --- a/src/Composer/Util/Filesystem.php +++ b/src/Composer/Util/Filesystem.php @@ -95,8 +95,8 @@ class Filesystem */ public function removeDirectory($directory) { - if (file_exists($directory) && is_link($directory)) { - return $this->unlink($directory); + if ($this->isSymlinkedDirectory($directory)) { + return $this->unlinkSymlinkedDirectory($directory); } if (!file_exists($directory) || !is_dir($directory)) { @@ -491,4 +491,49 @@ class Filesystem return unlink($path); } + + private function isSymlinkedDirectory($directory) + { + if (!is_dir($directory)) { + return false; + } + + $resolved = $this->resolveSymlinkedDirectorySymlink($directory); + + return is_link($resolved); + } + + /** + * @param string $directory + * + * @return bool + */ + private function unlinkSymlinkedDirectory($directory) + { + $resolved = $this->resolveSymlinkedDirectorySymlink($directory); + + return $this->unlink($resolved); + } + + /** + * resolve pathname to symbolic link of a directory + * + * @param string $pathname directory path to resolve + * + * @return string resolved path to symbolic link or original pathname (unresolved) + */ + private function resolveSymlinkedDirectorySymlink($pathname) + { + if (!is_dir($pathname)) { + return $pathname; + } + + $resolved = rtrim($pathname, '/'); + + if (!strlen($resolved)) { + return $pathname; + } + + return $resolved; + } }