Bug #85685

Uncaught TYPO3 Exception in form update wizard

Added by Sybille Peters over 1 year ago. Updated over 1 year ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
Form Framework
Target version:
-
Start date:
2018-07-30
Due date:
% Done:

0%

TYPO3 Version:
8
PHP Version:
Tags:
exception_handling
Complexity:
Is Regression:
Sprint Focus:

Description

Method FormFileExtensionUpdate::checkForUpdate calls FormPersistenceManager::retrieveYamlFilesFromStorageFolders which may throw Exception somewhere along the way.

If this is the case (as seen with 8.7.17), the Upgrade Wizard is no longer usable because the Exception gets thrown and breaks it.

While the error does occur in the indexing of files and only occurred here because of a rather exotically named file, I think this Update Wizard should in any case handle this and the general Upgrade Wizard should still be usable.

Stack Trace (complete stacktrace is attached as file exception-1314516809.txt):

Uncaught TYPO3 Exception
#1314516809: File /user_upload/niederlandistik/bilder/foto_ba\'s.JPG does not exist. (More information)

InvalidArgumentException thrown in file
/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/core/Classes/Resource/Driver/LocalDriver.php in line 253.

21 TYPO3\CMS\Core\Resource\Driver\LocalDriver::getFileInfoByIdentifier("/user_upload/niederlandistik/bilder/foto_ba\'s.JPG", array)

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/core/Classes/Resource/ResourceStorage.php:
01414:     public function getFileInfoByIdentifier($identifier, array $propertiesToExtract = [])
01415:     {
01416:         return $this->driver->getFileInfoByIdentifier($identifier, $propertiesToExtract);
01417:     }
01418: 

20 TYPO3\CMS\Core\Resource\ResourceStorage::getFileInfoByIdentifier("/user_upload/niederlandistik/bilder/foto_ba\'s.JPG")

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/core/Classes/Resource/Index/Indexer.php:
00308:     protected function gatherFileInformationArray($identifier)
00309:     {
00310:         $fileInfo = $this->storage->getFileInfoByIdentifier($identifier);
00311:         $fileInfo = $this->transformFromDriverFileInfoArrayToFileObjectFormat($fileInfo);
00312:         $fileInfo['type'] = $this->getFileType($fileInfo['mime_type']);

19 TYPO3\CMS\Core\Resource\Index\Indexer::gatherFileInformationArray("/user_upload/niederlandistik/bilder/foto_ba\'s.JPG")

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/core/Classes/Resource/Index/Indexer.php:
00069:             throw new \InvalidArgumentException('Invalid file identifier given. It must be of type string and not empty. "' . gettype($identifier) . '" given.', 1401732565);
00070:         }
00071:         $fileProperties = $this->gatherFileInformationArray($identifier);
00072:         $record = $this->getFileIndexRepository()->addRaw($fileProperties);
00073:         $fileObject = $this->getResourceFactory()->getFileObject($record['uid'], $record);

18 TYPO3\CMS\Core\Resource\Index\Indexer::createIndexEntry("/user_upload/niederlandistik/bilder/foto_ba\'s.JPG")

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/core/Classes/Resource/ResourceFactory.php:
00431:             $fileData = $this->getFileIndexRepository()->findOneByStorageUidAndIdentifier($storage->getUid(), $fileIdentifier);
00432:             if ($fileData === false) {
00433:                 $fileObject = $this->getIndexer($storage)->createIndexEntry($fileIdentifier);
00434:             } else {
00435:                 $fileObject = $this->getFileObject($fileData['uid'], $fileData);

17 TYPO3\CMS\Core\Resource\ResourceFactory::getFileObjectByStorageAndIdentifier(1, "/user_upload/niederlandistik/bilder/foto_ba\'s.JPG")

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/core/Classes/Resource/ResourceStorage.php:
01513:                 $fileObject = $this->getFileFactory()->getFileObject($rows[$identifier]['uid'], $rows[$identifier]);
01514:             } else {
01515:                 $fileObject = $this->getFileFactory()->getFileObjectByStorageAndIdentifier($this->getUid(), $identifier);
01516:             }
01517:             if ($fileObject instanceof FileInterface) {

16 TYPO3\CMS\Core\Resource\ResourceStorage::getFilesInFolder(TYPO3\CMS\Core\Resource\Folder, 0, 0, boolean, boolean, "", boolean)

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/core/Classes/Resource/Folder.php:
00225:         }
00226: 
00227:         $fileObjects = $this->storage->getFilesInFolder($this, $start, $numberOfItems, $useFilters, $recursive, $sort, $sortRev);
00228: 
00229:         $this->restoreBackedUpFiltersInStorage($backedUpFilters);

15 TYPO3\CMS\Core\Resource\Folder::getFiles(0, 0, 1, boolean)

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/form/Classes/Mvc/Persistence/FormPersistenceManager.php:
00373:                 0,
00374:                 Folder::FILTER_MODE_USE_OWN_AND_STORAGE_FILTERS,
00375:                 true
00376:             );
00377:             $filesFromStorageFolders = $filesFromStorageFolders + $files;

14 TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManager::retrieveYamlFilesFromStorageFolders()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/form/Classes/Hooks/FormFileExtensionUpdate.php:
00260: 
00261:         return array_filter(
00262:             $persistenceManager->retrieveYamlFilesFromStorageFolders(),
00263:             function (File $file) use ($yamlSource) {
00264:                 $isNewFormFile = StringUtility::endsWith(

13 TYPO3\CMS\Form\Hooks\FormFileExtensionUpdate::getAllStorageFormFilesWithOldNaming()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/form/Classes/Hooks/FormFileExtensionUpdate.php:
00052:         $updateNeeded = false;
00053: 
00054:         $allStorageFormFiles = $this->getAllStorageFormFilesWithOldNaming();
00055:         $referencedExtensionFormFiles = $this->groupReferencedExtensionFormFiles(
00056:             $this->getReferencedFormFilesWithOldNaming()

12 TYPO3\CMS\Form\Hooks\FormFileExtensionUpdate::checkForUpdate("")

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Classes/Updates/AbstractUpdate.php:
00117:     {
00118:         $explanation = '';
00119:         $result = $this->checkForUpdate($explanation);
00120:         return (bool)$result === true;
00121:     }

11 TYPO3\CMS\Install\Updates\AbstractUpdate::shouldRenderWizard()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Classes/Controller/Action/Tool/UpgradeWizard.php:
00142:                 ];
00143:             } else {
00144:                 if ($updateObject->shouldRenderWizard()) {
00145:                     // $explanation is changed by reference in Update objects!
00146:                     $explanation = '';

10 TYPO3\CMS\Install\Controller\Action\Tool\UpgradeWizard::listUpdates()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Classes/Controller/Action/Tool/UpgradeWizard.php:
00115:                 $actionMessages[] = $message;
00116:             }
00117:             $this->listUpdates();
00118:             $this->view->assign('updateAction', 'listUpdates');
00119:         }

9 TYPO3\CMS\Install\Controller\Action\Tool\UpgradeWizard::executeAction()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Classes/Controller/Action/AbstractAction.php:
00066:     {
00067:         $this->initializeHandle();
00068:         return $this->executeAction();
00069:     }
00070: 

8 TYPO3\CMS\Install\Controller\Action\AbstractAction::handle()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Classes/Controller/ToolController.php:
00185:         $toolAction->setPostValues($this->getPostValues());
00186:         $toolAction->setLastError($this->getLastError());
00187:         $this->output($toolAction->handle());
00188:     }
00189: }

7 TYPO3\CMS\Install\Controller\ToolController::dispatchAuthenticationActions()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Classes/Controller/ToolController.php:
00061:         $this->outputLoginFormIfNotAuthorized();
00062:         $this->registerExtensionConfigurationErrorHandler();
00063:         $this->dispatchAuthenticationActions();
00064:     }
00065: 

6 TYPO3\CMS\Install\Controller\ToolController::execute()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Classes/Http/RequestHandler.php:
00061:                 $controllerClassName = \TYPO3\CMS\Install\Controller\StepController::class;
00062:         }
00063:         GeneralUtility::makeInstance($controllerClassName)->execute();
00064:     }
00065: 

5 TYPO3\CMS\Install\Http\RequestHandler::handleRequest(TYPO3\CMS\Core\Http\ServerRequest)

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/core/Classes/Core/Bootstrap.php:
00314: 
00315:         // Execute the command which returns a Response object or NULL
00316:         $this->response = $requestHandler->handleRequest($request);
00317:         return $this;
00318:     }

4 TYPO3\CMS\Core\Core\Bootstrap::handleRequest(TYPO3\CMS\Core\Http\ServerRequest)

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Classes/Http/Application.php:
00073:     public function run(callable $execute = null)
00074:     {
00075:         $this->bootstrap->handleRequest(\TYPO3\CMS\Core\Http\ServerRequestFactory::fromGlobals());
00076: 
00077:         if ($execute !== null) {

3 TYPO3\CMS\Install\Http\Application::run()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Resources/Private/Php/install.php:
00101: call_user_func(function () {
00102:     $classLoader = require __DIR__ . '/../../../../../../vendor/autoload.php';
00103:     (new \TYPO3\CMS\Install\Http\Application($classLoader))->run();
00104: });

2 {closure}()

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/sysext/install/Resources/Private/Php/install.php:
00102:     $classLoader = require __DIR__ . '/../../../../../../vendor/autoload.php';
00103:     (new \TYPO3\CMS\Install\Http\Application($classLoader))->run();
00104: });

1 require("/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-…3/sysext/install/Resources/Private/Php/install.php")

/var/www/t3dev.uni-oldenburg.de/htdocs5/typo3_src-8.7.17/typo3/install.php:
00001: <?php
00002: 
00003: require __DIR__ . '/sysext/install/Resources/Private/Php/install.php';

File name that causes this (file exists):

ls -l fileadmin/user_upload/niederlandistik/bilder/foto_ba\\\'s.JPG 
-rw-r-----. 1 user group 194414 Nov  1  2012 fileadmin/user_upload/niederlandistik/bilder/foto_ba\'s.JPG

See also Wiki entry for Exception: https://wiki.typo3.org/Exception/CMS/1314516809

exception-1314516809.txt View (9.39 KB) Sybille Peters, 2018-07-30 13:32


Related issues

Related to TYPO3 Core - Bug #85544: The form definition upgrade wizard does not update all relevant plugin settings Closed 2018-07-12

History

#1 Updated by Ralf Zimmermann over 1 year ago

  • Related to Bug #85544: The form definition upgrade wizard does not update all relevant plugin settings added

#2 Updated by Sybille Peters over 1 year ago

  • Description updated (diff)

#3 Updated by Sybille Peters over 1 year ago

  • Subject changed from FormFileExtensionUpdate::checkForUpdate does not catch Exception to Uncaught TYPO3 Exception in form update wizard

#4 Updated by Sybille Peters over 1 year ago

  • Tags set to exception_handling

#5 Updated by Ralf Zimmermann over 1 year ago

You uploaded this file by hand, right? I think the file list module breaks to. If you upload this file through the backend then the filename will be sanitized. You should only use sanitized filenames.

#6 Updated by Sybille Peters over 1 year ago

I don't know how the file was uploaded. The file is from 2012 (or before), way before I started working on this TYPO3 installation. Personally, I would never give a file a name like that :(

It might have been uploaded before the sanitation was implemented the way it is now. In general, as far as I am aware, files like this were uploaded via the Backend for this installation (which has successfully been subjected to several major TYPO3 updates).

The point is, currently, some obscure problem could break the Upgrade Wizard. It's not ext:form's fault and you could argue that it is not ext:form's responsibility either. I would probably even agree, but I think at some point an exception should be caught. It shouldn't break the Upgrade Wizard.

If it makes more sense to catch the exception somewhere else along the call stack or solve this problem in a different way, I would certainly be open to suggestions.

(For me, I can solve the file issue directly, so I don't depend on a fix here, I am just assuming other installations may run into this problem or some problem where an exception gets thrown too.)

#7 Updated by Sybille Peters over 1 year ago

  • Status changed from New to Closed

Update: If the file is deleted and uploaded again, it will be properly sanitized.

While it may be prudent to catch Exceptions in any update wizard which calls functions that might throw them, I don't know what current practice is.

I think it is best to close this now (as it concerns edge cases that might better be handled elsewhere). Anyone can reopen and work on a patch if this makes more sense.

Also available in: Atom PDF