Skip to content

Commit

Permalink
IBX-7485: Skipped files with corrupted filenames when loading and del…
Browse files Browse the repository at this point in the history
…eting content

For more details see https://issues.ibexa.co/browse/IBX-7485 and #400

Key changes:

* Skipped files with corrupted filenames when loading and deleting

* [Tests] Added integration test
  • Loading branch information
barw4 authored Jan 31, 2024
1 parent 29489e4 commit 6e5fa6f
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 3 deletions.
105 changes: 105 additions & 0 deletions eZ/Publish/API/Repository/Tests/FieldType/ImageIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
*/
namespace eZ\Publish\API\Repository\Tests\FieldType;

use Doctrine\DBAL\ParameterType;
use DOMDocument;
use eZ\Publish\API\Repository\Values\Content\Content;
use eZ\Publish\API\Repository\Values\Content\Field;
use eZ\Publish\Core\FieldType\Image\Value as ImageValue;
use eZ\Publish\Core\Persistence\Legacy\Content\Gateway;

/**
* Integration test for use field type.
Expand Down Expand Up @@ -760,6 +763,108 @@ public function testRemovingDraftRemovesOldImage(): void
);
}

public function testDeleteImageWithCorruptedName(): void
{
$content = $this->publishNewImage(
__METHOD__,
new ImageValue(
[
'inputUri' => __DIR__ . '/_fixtures/image.jpg',
'fileName' => 'image.jpg',
'fileSize' => filesize(__DIR__ . '/_fixtures/image.jpg'),
'alternativeText' => 'Alternative',
]
),
[2]
);

$imageFieldDefinition = $content->getContentType()->getFieldDefinition('image');

$record = $this->fetchXML(
$content->id,
$content->getVersionInfo()->versionNo,
$imageFieldDefinition->id
);

$document = $this->corruptImageFieldXML($record);

$this->updateXML(
$content->id,
$content->getVersionInfo()->versionNo,
$imageFieldDefinition->id,
$document
);

$repository = $this->getRepository(false);
$contentService = $repository->getContentService();

$contentService->deleteContent($content->getVersionInfo()->getContentInfo());

// Expect no League\Flysystem\CorruptedPathDetected thrown
}

/**
* @return array<string,mixed>
*/
private function fetchXML(int $contentId, int $versionNo, int $fieldDefinitionId): array
{
$connection = $this->getRawDatabaseConnection();

$query = $connection->createQueryBuilder();
$query
->select('data_text')
->from(Gateway::CONTENT_FIELD_TABLE)
->andWhere('contentclassattribute_id = :contentclassattribute_id')
->andWhere('version = :version')
->andWhere('contentobject_id = :contentobject_id')
->setParameter('contentclassattribute_id', $fieldDefinitionId, ParameterType::INTEGER)
->setParameter('version', $versionNo, ParameterType::INTEGER)
->setParameter('contentobject_id', $contentId, ParameterType::INTEGER);
$result = $query->execute();

return $result->fetchAssociative();
}

/**
* @param array<string,mixed> $row
*/
private function corruptImageFieldXML(array $row): DOMDocument
{
$corruptedChar = '­';

$document = new DOMDocument('1.0', 'utf-8');
$document->loadXML($row['data_text']);
$elements = $document->getElementsByTagName('ezimage');
$element = $elements->item(0);
$element->setAttribute('filename', $element->getAttribute('filename') . $corruptedChar);
$element->setAttribute('url', $element->getAttribute('url') . $corruptedChar);

return $document;
}

private function updateXML(
int $contentId,
int $versionNo,
int $fieldDefinitionId,
DOMDocument $document
): void {
$connection = $this->getRawDatabaseConnection();

$query = $connection->createQueryBuilder();
$query
->update(Gateway::CONTENT_FIELD_TABLE)
->set('data_text', ':data_text')
->setParameter('data_text', $document->saveXML(), ParameterType::STRING)
->andWhere('contentclassattribute_id = :contentclassattribute_id')
->andWhere('version = :version')
->andWhere('contentobject_id = :contentobject_id')
->setParameter('contentclassattribute_id', $fieldDefinitionId, ParameterType::INTEGER)
->setParameter('version', $versionNo, ParameterType::INTEGER)
->setParameter('contentobject_id', $contentId, ParameterType::INTEGER);

$query->execute();
}

/**
* @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
Expand Down
3 changes: 2 additions & 1 deletion eZ/Publish/Core/IO/IOBinarydataHandler/Flysystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use eZ\Publish\Core\IO\UrlDecorator;
use eZ\Publish\SPI\IO\BinaryFileCreateStruct;
use League\Flysystem\AdapterInterface;
use League\Flysystem\CorruptedPathDetected;
use League\Flysystem\FileExistsException;
use League\Flysystem\FileNotFoundException as FlysystemNotFoundException;
use League\Flysystem\FilesystemInterface;
Expand Down Expand Up @@ -56,7 +57,7 @@ public function delete($spiBinaryFileId)
{
try {
$this->filesystem->delete($spiBinaryFileId);
} catch (FlysystemNotFoundException $e) {
} catch (FlysystemNotFoundException|CorruptedPathDetected $e) {
throw new BinaryFileNotFoundException($spiBinaryFileId, $e);
}
}
Expand Down
9 changes: 7 additions & 2 deletions eZ/Publish/Core/IO/IOMetadataHandler/Flysystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use eZ\Publish\Core\IO\IOMetadataHandler;
use eZ\Publish\SPI\IO\BinaryFile as SPIBinaryFile;
use eZ\Publish\SPI\IO\BinaryFileCreateStruct as SPIBinaryFileCreateStruct;
use League\Flysystem\CorruptedPathDetected;
use League\Flysystem\FileNotFoundException;
use League\Flysystem\FilesystemInterface;

Expand Down Expand Up @@ -47,7 +48,7 @@ public function load($spiBinaryFileId)
{
try {
$info = $this->filesystem->getMetadata($spiBinaryFileId);
} catch (FileNotFoundException $e) {
} catch (FileNotFoundException|CorruptedPathDetected $e) {
throw new BinaryFileNotFoundException($spiBinaryFileId);
}

Expand All @@ -64,7 +65,11 @@ public function load($spiBinaryFileId)

public function exists($spiBinaryFileId)
{
return $this->filesystem->has($spiBinaryFileId);
try {
return $this->filesystem->has($spiBinaryFileId);
} catch (CorruptedPathDetected $e) {
return false;
}
}

public function getMimeType($spiBinaryFileId)
Expand Down

0 comments on commit 6e5fa6f

Please sign in to comment.