[BUGFIX] Handle symlink on extension update 26/18826/4
authorPhilipp Gampe <philipp.gampe@typo3.org>
Sun, 10 Mar 2013 16:15:27 +0000 (17:15 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Mon, 11 Mar 2013 19:41:51 +0000 (20:41 +0100)
If an extension is updated and the extension in the file
system is a symlink to a different directory, all
target directory contents is removed and the update fails.

Introduce a check for symlink and just remove the
symlink in this case.

Resolves: #46158
Releases: 6.1, 6.0
Change-Id: I112ae7192fb0edf77ebd703a61804dc09ca506a4
Reviewed-on: https://review.typo3.org/18826
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/extensionmanager/Classes/Utility/FileHandlingUtility.php
typo3/sysext/extensionmanager/Tests/Unit/Utility/FileHandlingUtilityTest.php

index 9293bce..8b55ac4 100644 (file)
@@ -250,8 +250,13 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @return void
         */
        public function removeDirectory($extDirPath) {
-               $res = GeneralUtility::rmdir($extDirPath, TRUE);
-               if ($res === FALSE) {
+               $extensionPathWithoutTrailingSlash = rtrim($extDirPath, DIRECTORY_SEPARATOR);
+               if (is_link($extensionPathWithoutTrailingSlash)) {
+                       $result = unlink($extensionPathWithoutTrailingSlash);
+               } else {
+                       $result = GeneralUtility::rmdir($extDirPath, TRUE);
+               }
+               if ($result === FALSE) {
                        throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_remove_dir'), $this->getRelativePath($extDirPath)), 1337280415);
                }
        }
index b349b56..88639f7 100644 (file)
@@ -36,12 +36,24 @@ class FileHandlingUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase
        protected $fakedExtensions = array();
 
        /**
+        * @var array List of resources (files or empty directories) that need to be removed in tearDown() again
+        */
+       protected $resourcesToRemove = array();
+
+       /**
         * @return void
         */
        public function tearDown() {
                foreach ($this->fakedExtensions as $extension => $dummy) {
                        \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir(PATH_site . 'typo3conf/ext/' . $extension, TRUE);
                }
+               foreach ($this->resourcesToRemove as $resource) {
+                       if (file_exists($resource) && is_file($resource)) {
+                               unlink($resource);
+                       } elseif(file_exists($resource) && is_dir($resource)) {
+                               rmdir($resource);
+                       }
+               }
        }
 
        /**
@@ -170,6 +182,43 @@ class FileHandlingUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase
         * @test
         * @return void
         */
+       public function removeDirectoryRemovesSymlink() {
+               $absoluteSymlinkPath = PATH_site . 'typo3temp/' . uniqid('test_symlink_');
+               $absoluteFilePath = PATH_site . 'typo3temp/' . uniqid('test_file_');
+               touch($absoluteFilePath);
+               $this->resourcesToRemove[] = $absoluteFilePath;
+               symlink($absoluteFilePath, $absoluteSymlinkPath);
+               $fileHandler = new \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility();
+               $fileHandler->removeDirectory($absoluteSymlinkPath);
+               $this->assertFalse(is_link($absoluteSymlinkPath));
+       }
+
+       /**
+        * @test
+        * @return void
+        */
+       public function removeDirectoryDoesNotRemoveContentOfSymlinkedTargetDirectory() {
+               $absoluteSymlinkPath = PATH_site . 'typo3temp/' . uniqid('test_symlink_');
+               $absoluteDirectoryPath = PATH_site . 'typo3temp/' . uniqid('test_dir_') . '/';
+               $relativeFilePath = uniqid('test_file_');
+
+               mkdir($absoluteDirectoryPath);
+               touch($absoluteDirectoryPath . $relativeFilePath);
+
+               $this->resourcesToRemove[] = $absoluteDirectoryPath . $relativeFilePath;
+               $this->resourcesToRemove[] = $absoluteDirectoryPath;
+
+               symlink($absoluteDirectoryPath, $absoluteSymlinkPath);
+
+               $fileHandler = new \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility();
+               $fileHandler->removeDirectory($absoluteSymlinkPath);
+               $this->assertTrue(is_file($absoluteDirectoryPath . $relativeFilePath));
+       }
+
+       /**
+        * @test
+        * @return void
+        */
        public function unpackExtensionFromExtensionDataArrayCreatesTheExtensionDirectory() {
                $extensionData = array(
                        'extKey' => 'test'