Bug #66341
closedprocessing folders are not created by upgrade wizard, forcing specific workflow during migration
100%
Description
When migrating a website from 4.5 to 6.2, the upgrade wizard does not fully initialize the automatically created FAL storage as it does not create any processing folders. This becomes an issue if getFile
is called on an instance of ResourceStorage
which has evaluatePermissions
set to true
, which is the case if e.g. dam_falmigration is being run from CLI with command php typo3/cli_dispatch.phpsh extbase dammigration:migratedamrecords
. This results in a loop inside ResourceStorage
; with custom debugging output to trace the loop (each number corresponds to a specific function, described on the a
-line, each character to another line in that function):
1a entry TYPO3\CMS\Core\Resource\ResourceStorage::getFile, uid 1, identifier user_upload/folder/file.jpg 2a entry TYPO3\CMS\Core\Resource\ResourceFactory::getFileObjectByStorageAndIdentifier, uid 1 file identifier user_upload/folder/file.jpg 2b checking $storage->isWithinProcessingFolder($fileIdentifier) 3a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinProcessingFolder with identifier user_upload/folder/file.jpg 3b starting iteration over getProcessingFolders() 4a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolders 4b instantiation of TYPO3\CMS\Core\Resource\StorageRepository 4c find all on storage repository 4d iterate over all storages 4e storage uid 1, name fileadmin/ (auto-created) 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5b processing folder is not set 5c default set 5e processingfolder is _processed_ 5g checking processing folder _processed_ 5h creating folder 6a entry TYPO3\CMS\Core\Resource\ResourceStorage::createFolder 6b parent folder is null => using root level folder 6d going to check if add is a permitted folder action 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action add, folder identifier: / 7c folder === null? 7e read check 7g write check 7h $isWriteCheck = TRUE 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8c $this->evaluatePermissions true 8e get identifier 8f identifier: /, next call is isWithinProcessingFolder 3a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinProcessingFolder with identifier / 3b starting iteration over getProcessingFolders() 4a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolders 4b instantiation of TYPO3\CMS\Core\Resource\StorageRepository 4c find all on storage repository 4d iterate over all storages 4e storage uid 1, name fileadmin/ (auto-created) 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5b processing folder is not set 5c default set 5e processingfolder is _processed_ 5g checking processing folder _processed_ 5h creating folder 6a entry TYPO3\CMS\Core\Resource\ResourceStorage::createFolder 6b parent folder is null => using root level folder 6d going to check if add is a permitted folder action 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action add, folder identifier: / ...
What happens is that TYPO3\CMS\Core\Resource\ResourceStorage::getFile
implicitely checks if processing folders have already been created but they haven't yet. Using isWithinProcessingFolder
, TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission
then checks if the storage's root folder /
belongs to the processing folder. Since evaluatePermissions
is true
, this results in getting the processing folders yet again in an inifinite recursion as the processing folder still not exists, permissions are being checked again and everything repeats.
When the filelist module is being called for the first time by a backend user, the same debugging code produces a partial (incompletely commented) output of:
7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: / 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: /templates/ 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: /user_upload/ 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: /_temp_/ 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 4a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolders 4b instantiation of TYPO3\CMS\Core\Resource\StorageRepository 4c find all on storage repository 4d iterate over all storages 4e storage uid 1, name fileadmin/ (auto-created) 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5b processing folder is not set 5c default set 5e processingfolder is _processed_ 5g checking processing folder _processed_ 5h creating folder 6a entry TYPO3\CMS\Core\Resource\ResourceStorage::createFolder 6b parent folder is null => using root level folder 6d going to check if add is a permitted folder action 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action add, folder identifier: / 7c folder === null? 7e read check 7g write check 7h $isWriteCheck = TRUE 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 6f permitted 6g creating folder $this->getDriver()->createFolder($folderName = "_processed_", $parentFolder->getIdentifier() = "/", TRUE) 6h now getting folder /_processed_/ 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: /_processed_/ 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 6i emitting post folder add signal 6j done
It's visible that certain folders are initially created only when first checked by the filelist module. Note that there is no line 8c $this->evaluatePermissions true
if filelist is called, so evaluatePermissions
is false
. This prevents the loop that's happening on CLI.
Afterwards, dam_falmigration
does work as expected as the processing folder has already been created and the looping check is no longer performed:
1a entry TYPO3\CMS\Core\Resource\ResourceStorage::getFile, uid 1, identifier user_upload/folder/file.jpg 2a entry TYPO3\CMS\Core\Resource\ResourceFactory::getFileObjectByStorageAndIdentifier, uid 1 file identifier user_upload/folder/file.jpg 2b checking $storage->isWithinProcessingFolder($fileIdentifier) 3a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinProcessingFolder with identifier user_upload/folder/file.jpg 3b starting iteration over getProcessingFolders() 4a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolders 4b instantiation of TYPO3\CMS\Core\Resource\StorageRepository 4c find all on storage repository 4d iterate over all storages 4e storage uid 1, name fileadmin/ (auto-created) 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5b processing folder is not set 5c default set 5e processingfolder is _processed_ 5g checking processing folder _processed_ 5i folder already exists 5j got data
dam_falmigration
does not manipulate evaluatePermissions
, so this appears to be a bug in Core...
I could imagine two ways to fix this:
- When the upgrade wizard is creating a FAL storage for the first time, it should initialize all folders that would otherwise only be created upon entering filelist module for the first time. Or:
checkFolderActionPermission
should skip theisWithinProcessingFolder
check if the storage root folder/
is being checked as the expected result should always befalse
? Note that this assumption should be verified by the FAL/Core team; I'm primarily a user and don't know much about those internals of TYPO3. :)
A workaround, obviously, is to call the BE module filelist immediately upon migration, before trying to do anything else. But that shouldn't be necessary in my opinion - what's the upgrade wizard for?
Files