Commit 3e2758d1 authored by Susanne Moog's avatar Susanne Moog Committed by Benni Mack
Browse files

[BUGFIX] Log invalid hash generation in FAL Indexer

The FAL Indexer uses the driver to get a hash for a file. In certain
circumstances (and with 3rd party drivers) the hash generated might be
null or invalid. In that case the ResourceStorage now throws an
exception to alert the developer to the wrong return value. At the same
time the Indexer catches and logs the exception to not interrupt the
whole indexing flow because of it.

For more information, please take a look at the ticket.

Resolves: #66397
Releases: master
Change-Id: I0f97cd23127e96b6d94161a9296750cbe3421075
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/59893


Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Daniel Goerz's avatarDaniel Goerz <daniel.goerz@posteo.de>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
Reviewed-by: Frank Nägler's avatarFrank Nägler <frank.naegler@typo3.org>
Reviewed-by: default avatarGuido Schmechel <guido.schmechel@brandung.de>
Reviewed-by: Daniel Goerz's avatarDaniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent fea0bdcf
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Core\Resource\Exception;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
/**
* An exception when something is wrong with the Hash
* Is thrown for example when the driver returns an unexpected (non-string) hash value
*/
class InvalidHashException extends \TYPO3\CMS\Core\Resource\Exception
{
}
...@@ -14,8 +14,11 @@ namespace TYPO3\CMS\Core\Resource\Index; ...@@ -14,8 +14,11 @@ namespace TYPO3\CMS\Core\Resource\Index;
* The TYPO3 project - inspiring people to share! * The TYPO3 project - inspiring people to share!
*/ */
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use TYPO3\CMS\Core\Resource\Exception\IllegalFileExtensionException; use TYPO3\CMS\Core\Resource\Exception\IllegalFileExtensionException;
use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException; use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException;
use TYPO3\CMS\Core\Resource\Exception\InvalidHashException;
use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Resource\ResourceStorage; use TYPO3\CMS\Core\Resource\ResourceStorage;
...@@ -24,10 +27,12 @@ use TYPO3\CMS\Core\Type\File\ImageInfo; ...@@ -24,10 +27,12 @@ use TYPO3\CMS\Core\Type\File\ImageInfo;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
/** /**
* The New FAL Indexer * The FAL Indexer
*/ */
class Indexer class Indexer implements LoggerAwareInterface
{ {
use LoggerAwareTrait;
/** /**
* @var array * @var array
*/ */
...@@ -228,34 +233,43 @@ class Indexer ...@@ -228,34 +233,43 @@ class Indexer
protected function processChangedAndNewFiles() protected function processChangedAndNewFiles()
{ {
foreach ($this->filesToUpdate as $identifier => $data) { foreach ($this->filesToUpdate as $identifier => $data) {
if ($data == null) { try {
// search for files with same content hash in indexed storage if ($data === null) {
$fileHash = $this->storage->hashFileByIdentifier($identifier, 'sha1'); // search for files with same content hash in indexed storage
$files = $this->getFileIndexRepository()->findByContentHash($fileHash); $fileHash = $this->storage->hashFileByIdentifier($identifier, 'sha1');
$fileObject = null; $files = $this->getFileIndexRepository()->findByContentHash($fileHash);
if (!empty($files)) { $fileObject = null;
foreach ($files as $fileIndexEntry) { if (!empty($files)) {
// check if file is missing then we assume it's moved/renamed foreach ($files as $fileIndexEntry) {
if (!$this->storage->hasFile($fileIndexEntry['identifier'])) { // check if file is missing then we assume it's moved/renamed
$fileObject = $this->getResourceFactory()->getFileObject($fileIndexEntry['uid'], $fileIndexEntry); if (!$this->storage->hasFile($fileIndexEntry['identifier'])) {
$fileObject->updateProperties([ $fileObject = $this->getResourceFactory()->getFileObject(
'identifier' => $identifier $fileIndexEntry['uid'],
]); $fileIndexEntry
$this->updateIndexEntry($fileObject); );
$this->identifiedFileUids[] = $fileObject->getUid(); $fileObject->updateProperties(
break; [
'identifier' => $identifier,
]
);
$this->updateIndexEntry($fileObject);
$this->identifiedFileUids[] = $fileObject->getUid();
break;
}
} }
} }
// create new index when no missing file with same content hash is found
if ($fileObject === null) {
$fileObject = $this->createIndexEntry($identifier);
$this->identifiedFileUids[] = $fileObject->getUid();
}
} else {
// update existing file
$fileObject = $this->getResourceFactory()->getFileObject($data['uid'], $data);
$this->updateIndexEntry($fileObject);
} }
// create new index when no missing file with same content hash is found } catch (InvalidHashException $e) {
if ($fileObject === null) { $this->logger->error('Unable to create hash for file ' . $identifier);
$fileObject = $this->createIndexEntry($identifier);
$this->identifiedFileUids[] = $fileObject->getUid();
}
} else {
// update existing file
$fileObject = $this->getResourceFactory()->getFileObject($data['uid'], $data);
$this->updateIndexEntry($fileObject);
} }
} }
} }
...@@ -294,8 +308,9 @@ class Indexer ...@@ -294,8 +308,9 @@ class Indexer
* *
* @param string $identifier * @param string $identifier
* @return array * @return array
* @throws \TYPO3\CMS\Core\Resource\Exception\InvalidHashException
*/ */
protected function gatherFileInformationArray($identifier) protected function gatherFileInformationArray($identifier): array
{ {
$fileInfo = $this->storage->getFileInfoByIdentifier($identifier); $fileInfo = $this->storage->getFileInfoByIdentifier($identifier);
$fileInfo = $this->transformFromDriverFileInfoArrayToFileObjectFormat($fileInfo); $fileInfo = $this->transformFromDriverFileInfoArrayToFileObjectFormat($fileInfo);
......
...@@ -23,6 +23,7 @@ use TYPO3\CMS\Core\Log\LogManager; ...@@ -23,6 +23,7 @@ use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\Registry; use TYPO3\CMS\Core\Registry;
use TYPO3\CMS\Core\Resource\Driver\StreamableDriverInterface; use TYPO3\CMS\Core\Resource\Driver\StreamableDriverInterface;
use TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException; use TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException;
use TYPO3\CMS\Core\Resource\Exception\InvalidHashException;
use TYPO3\CMS\Core\Resource\Exception\InvalidTargetFolderException; use TYPO3\CMS\Core\Resource\Exception\InvalidTargetFolderException;
use TYPO3\CMS\Core\Resource\Index\FileIndexRepository; use TYPO3\CMS\Core\Resource\Index\FileIndexRepository;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry; use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
...@@ -1275,6 +1276,7 @@ class ResourceStorage implements ResourceStorageInterface ...@@ -1275,6 +1276,7 @@ class ResourceStorage implements ResourceStorageInterface
* *
* @param FileInterface $fileObject * @param FileInterface $fileObject
* @param string $hash * @param string $hash
* @throws \TYPO3\CMS\Core\Resource\Exception\InvalidHashException
* @return string * @return string
*/ */
public function hashFile(FileInterface $fileObject, $hash) public function hashFile(FileInterface $fileObject, $hash)
...@@ -1287,12 +1289,16 @@ class ResourceStorage implements ResourceStorageInterface ...@@ -1287,12 +1289,16 @@ class ResourceStorage implements ResourceStorageInterface
* *
* @param string $fileIdentifier * @param string $fileIdentifier
* @param string $hash * @param string $hash
* * @throws \TYPO3\CMS\Core\Resource\Exception\InvalidHashException
* @return string * @return string
*/ */
public function hashFileByIdentifier($fileIdentifier, $hash) public function hashFileByIdentifier($fileIdentifier, $hash)
{ {
return $this->driver->hash($fileIdentifier, $hash); $hash = $this->driver->hash($fileIdentifier, $hash);
if (!is_string($hash) || $hash === '') {
throw new InvalidHashException('Hash has to be non-empty string.', 1551950301);
}
return $hash;
} }
/** /**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment