diff --git a/typo3/sysext/core/Classes/Resource/ResourceStorage.php b/typo3/sysext/core/Classes/Resource/ResourceStorage.php index bdfcafa4829579b5105ea484a7bd2cb0cf115c3f..86e9e85b781f11baf8546f15ae8e0cff23268acf 100644 --- a/typo3/sysext/core/Classes/Resource/ResourceStorage.php +++ b/typo3/sysext/core/Classes/Resource/ResourceStorage.php @@ -2008,11 +2008,11 @@ class ResourceStorage implements ResourceStorageInterface */ public function renameFile($file, $targetFileName, $conflictMode = DuplicationBehavior::RENAME) { - // The name should be different from the current. - if ($file->getName() === $targetFileName) { + $sanitizedTargetFileName = $this->driver->sanitizeFileName($targetFileName); + // The new name should be different from the current. + if ($file->getName() === $sanitizedTargetFileName) { return $file; } - $sanitizedTargetFileName = $this->driver->sanitizeFileName($targetFileName); $this->assureFileRenamePermissions($file, $sanitizedTargetFileName); $this->eventDispatcher->dispatch( new BeforeFileRenamedEvent($file, $sanitizedTargetFileName) diff --git a/typo3/sysext/core/Tests/Functional/Resource/ResourceStorageTest.php b/typo3/sysext/core/Tests/Functional/Resource/ResourceStorageTest.php index 251b2c36337ad47e06150c69109169a3a32f0af5..df3cc0d405e6436d17b0312ff5dcbc7ce6dc52ec 100644 --- a/typo3/sysext/core/Tests/Functional/Resource/ResourceStorageTest.php +++ b/typo3/sysext/core/Tests/Functional/Resource/ResourceStorageTest.php @@ -22,6 +22,7 @@ use TYPO3\CMS\Core\Resource\Driver\AbstractDriver; use TYPO3\CMS\Core\Resource\Driver\LocalDriver; use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Resource\Folder; +use TYPO3\CMS\Core\Resource\Index\Indexer; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Resource\ResourceStorage; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -110,6 +111,7 @@ final class ResourceStorageTest extends FunctionalTestCase $localDriver->method('getPermissions')->willReturn($permissionsFromDriver); $mockedResourceFactory = $this->createMock(ResourceFactory::class); $mockedFolder = $this->createMock(Folder::class); + // Let all other checks pass $subject = $this->getMockBuilder(ResourceStorage::class) ->onlyMethods(['isWritable', 'isBrowsable', 'checkUserActionPermission', 'getResourceFactoryInstance']) @@ -252,4 +254,40 @@ final class ResourceStorageTest extends FunctionalTestCase $subject->_set('driver', $mockedDriver); $subject->deleteFolder($folderMock); } + + /** + * @test + */ + public function renameFileWillCallRenameFileIfUnsanitizedAndNoChangeInTargetFilename(): void + { + $driverMock = $this->getMockBuilder(LocalDriver::class) + ->onlyMethods(['renameFile', 'sanitizeFileName']) + ->disableOriginalConstructor() + ->getMock(); + $driverMock->method('sanitizeFileName') + ->willReturn('a_b.jpg'); + $driverMock->expects(self::once()) + ->method('renameFile') + ->with('/a b.jpg', 'a_b.jpg'); + $indexerMock = $this->getMockBuilder(Indexer::class) + ->onlyMethods(['updateIndexEntry']) + ->disableOriginalConstructor() + ->getMock(); + + $subject = $this->getMockBuilder(ResourceStorage::class) + ->onlyMethods(['assureFileRenamePermissions', 'getIndexer']) + ->setConstructorArgs([$driverMock, ['name' => 'testing'], new NoopEventDispatcher()]) + ->getMock(); + $subject->method('getIndexer') + ->willReturn($indexerMock); + $file = new File( + [ + 'identifier' => '/a b.jpg', + 'name' => 'a b.jpg', + ], + $subject, + ); + $subject->renameFile($file, 'a b.jpg'); + } + }