‪TYPO3CMS  10.4
ImageMagickFileTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use org\bovigo\vfs\vfsStream;
21 use org\bovigo\vfs\vfsStreamDirectory;
22 use PHPUnit\Framework\MockObject\MockObject;
27 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
28 
29 class ‪ImageMagickFileTest extends FunctionalTestCase
30 {
34  private ‪$directory;
35 
36  protected function ‪setUp(): void
37  {
38  parent::setUp();
39 
40  $fixturePath = __DIR__ . '/Fixtures';
41  $structure = [];
42  $this->‪addFiles($structure, ['file.ai', 'file.ai.jpg'], $fixturePath . '/file.ai');
43  $this->‪addFiles($structure, ['file.bmp', 'file.bmp.jpg'], $fixturePath . '/file.bmp');
44  $this->‪addFiles($structure, ['file.gif', 'file.gif.jpg'], $fixturePath . '/file.gif');
45  $this->‪addFiles($structure, ['file.fax', 'file.fax.jpg'], $fixturePath . '/file.fax');
46  $this->‪addFiles($structure, ['file.jpg', 'file.jpg.png'], $fixturePath . '/file.jpg');
47  $this->‪addFiles($structure, ['file.png', 'file.png.jpg'], $fixturePath . '/file.png');
48  $this->‪addFiles($structure, ['file.svg', 'file.svg.jpg'], $fixturePath . '/file.svg');
49  $this->‪addFiles($structure, ['file.tif', 'file.tif.jpg'], $fixturePath . '/file.tif');
50  $this->‪addFiles($structure, ['file.webp', 'file.webp.jpg'], $fixturePath . '/file.webp');
51  $this->‪addFiles($structure, ['file.pdf', 'file.pdf.jpg'], $fixturePath . '/file.pdf');
52  $this->‪addFiles($structure, ['file.ps', 'file.ps.jpg'], $fixturePath . '/file.ps');
53  $this->‪addFiles($structure, ['file.eps', 'file.eps.jpg'], $fixturePath . '/file.eps');
54  $this->directory = vfsStream::setup('root', null, $structure);
55  }
56 
57  protected function ‪tearDown(): void
58  {
59  unset($this->directory);
60  parent::tearDown();
61  }
62 
66  public function ‪framesAreConsideredDataProvider(): array
67  {
68  return [
69  'file.pdf' => ['file.pdf', null, '\'pdf:{directory}/file.pdf\''],
70  'file.pdf[0]' => ['file.pdf', 0, '\'pdf:{directory}/file.pdf[0]\''],
71  ];
72  }
73 
82  public function ‪framesAreConsidered(string $fileName, ?int $frame, string $expectation)
83  {
84  $expectation = $this->‪substituteVariables($expectation);
85  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
86  $file = ‪ImageMagickFile::fromFilePath($filePath, $frame);
87  self::assertSame($expectation, (string)$file);
88  }
89 
93  public function ‪resultIsEscapedDataProvider(): array
94  {
95  // probably Windows system
96  if (DIRECTORY_SEPARATOR === '\\') {
97  return [
98  'without frame' => ['file.pdf', null, '"pdf:{directory}/file.pdf"'],
99  'with first frame' => ['file.pdf', 0, '"pdf:{directory}/file.pdf[0]"'],
100  'special literals' => ['\'`%$!".png', 0, '"png:{directory}/\'` $ .png[0]"'],
101  ];
102  }
103  // probably Unix system
104  return [
105  'without frame' => ['file.pdf', null, '\'pdf:{directory}/file.pdf\''],
106  'with first frame' => ['file.pdf', 0, '\'pdf:{directory}/file.pdf[0]\''],
107  'special literals' => ['\'`%$!".png', 0, '\'png:{directory}/\'\\\'\'`%$!".png[0]\''],
108  ];
109  }
110 
119  public function ‪resultIsEscaped(string $fileName, ?int $frame, string $expectation)
120  {
121  $expectation = $this->‪substituteVariables($expectation);
122  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
123  $file = ‪ImageMagickFile::fromFilePath($filePath, $frame);
124  self::assertSame($expectation, (string)$file);
125  }
126 
130  public function ‪fileStatementIsResolvedDataProvider(): array
131  {
132  return [
133  'file.ai' => ['file.ai', '\'pdf:{directory}/file.ai\''],
134  'file.ai.jpg' => ['file.ai.jpg', '\'pdf:{directory}/file.ai.jpg\''],
135  'file.gif' => ['file.gif', '\'gif:{directory}/file.gif\''],
136  'file.gif.jpg' => ['file.gif.jpg', '\'gif:{directory}/file.gif.jpg\''],
137  'file.jpg' => ['file.jpg', '\'jpg:{directory}/file.jpg\''],
138  'file.jpg.png' => ['file.jpg.png', '\'jpg:{directory}/file.jpg.png\''],
139  'file.png' => ['file.png', '\'png:{directory}/file.png\''],
140  'file.png.jpg' => ['file.png.jpg', '\'png:{directory}/file.png.jpg\''],
141  'file.svg' => ['file.svg', '\'svg:{directory}/file.svg\''],
142  'file.svg.jpg' => ['file.svg.jpg', '\'svg:{directory}/file.svg.jpg\''],
143  'file.tif' => ['file.tif', '\'tif:{directory}/file.tif\''],
144  'file.tif.jpg' => ['file.tif.jpg', '\'tif:{directory}/file.tif.jpg\''],
145  'file.webp' => ['file.webp', '\'webp:{directory}/file.webp\''],
146  'file.webp.jpg' => ['file.webp.jpg', '\'webp:{directory}/file.webp.jpg\''],
147  'file.pdf' => ['file.pdf', '\'pdf:{directory}/file.pdf\''],
148  'file.pdf.jpg' => ['file.pdf.jpg', '\'pdf:{directory}/file.pdf.jpg\''],
149  // accepted, since postscript files are converted using 'jpg:' format
150  'file.ps.jpg' => ['file.ps.jpg', '\'jpg:{directory}/file.ps.jpg\''],
151  'file.eps.jpg' => ['file.eps.jpg', '\'jpg:{directory}/file.eps.jpg\''],
152  ];
153  }
154 
162  public function ‪fileStatementIsResolved(string $fileName, string $expectation)
163  {
164  $expectation = $this->‪substituteVariables($expectation);
165  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
166  $file = ‪ImageMagickFile::fromFilePath($filePath, null);
167  self::assertSame($expectation, (string)$file);
168  }
169 
177  {
178  return [
179  'file.ai.jpg' => ['file.ai.jpg', '\'jpg:{directory}/file.ai.jpg\'', 'inode/x-empty'],
180  'file.bmp.jpg' => ['file.bmp.jpg', '\'jpg:{directory}/file.bmp.jpg\'', 'inode/x-empty'],
181  'file.fax.jpg' => ['file.fax.jpg', '\'jpg:{directory}/file.fax.jpg\'', 'inode/x-empty'],
182  'file.gif.jpg' => ['file.gif.jpg', '\'jpg:{directory}/file.gif.jpg\'', 'inode/x-empty'],
183  'file.jpg' => ['file.jpg', '\'jpg:{directory}/file.jpg\'', 'inode/x-empty'],
184  'file.jpg.png' => ['file.jpg.png', '\'png:{directory}/file.jpg.png\'', 'inode/x-empty'],
185  'file.png' => ['file.png', '\'png:{directory}/file.png\'', 'inode/x-empty'],
186  'file.png.jpg' => ['file.png.jpg', '\'jpg:{directory}/file.png.jpg\'', 'inode/x-empty'],
187  'file.svg.jpg' => ['file.svg.jpg', '\'jpg:{directory}/file.svg.jpg\'', 'inode/x-empty'],
188  'file.tif' => ['file.tif', '\'tif:{directory}/file.tif\'', 'inode/x-empty'],
189  'file.tif.jpg' => ['file.tif.jpg', '\'jpg:{directory}/file.tif.jpg\'', 'inode/x-empty'],
190  'file.webp' => ['file.webp', '\'webp:{directory}/file.webp\'', 'inode/x-empty'],
191  'file.webp.jpg' => ['file.webp.jpg', '\'jpg:{directory}/file.webp.jpg\'', 'inode/x-empty'],
192  'file.pdf.jpg' => ['file.pdf.jpg', '\'jpg:{directory}/file.pdf.jpg\'', 'inode/x-empty'],
193  ];
194  }
195 
204  public function ‪fileStatementIsResolvedForEnforcedMimeType(string $fileName, string $expectation, string $mimeType)
205  {
206  $this->‪simulateNextFileInfoInvocation($mimeType);
207  $expectation = $this->‪substituteVariables($expectation);
208  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
209  $file = ‪ImageMagickFile::fromFilePath($filePath, null);
210  self::assertSame($expectation, (string)$file);
211  }
212 
217  {
218  return [
219  'file.fax' => ['file.fax', '\'g3:{directory}/file.fax\''],
220  'file.bmp' => ['file.bmp', '\'dib:{directory}/file.bmp\''],
221  ];
222  }
223 
231  public function ‪fileStatementIsResolvedForConfiguredMimeType(string $fileName, string $expectation)
232  {
233  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['g3'] = 'image/g3fax';
234  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['fax'] = 'image/g3fax';
235  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['dib'] = 'image/x-ms-bmp';
236  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['bmp'] = 'image/x-ms-bmp';
237 
238  $expectation = $this->‪substituteVariables($expectation);
239  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
240  $file = ‪ImageMagickFile::fromFilePath($filePath, null);
241  self::assertSame($expectation, (string)$file);
242  }
243 
247  public function ‪fileStatementIsDeniedDataProvider(): array
248  {
249  return [
250  'file.ps' => ['file.ps'],
251  'file.eps' => ['file.eps'],
252  // denied since not defined in allowed extensions
253  'file.ai' => ['file.ai', 'inode/x-empty'],
254  'file.svg' => ['file.svg', 'inode/x-empty'],
255  'file.pdf' => ['file.pdf', 'inode/x-empty'],
256  ];
257  }
258 
266  public function ‪fileStatementIsDenied(string $fileName, string $mimeType = null)
267  {
268  self::expectException(Exception::class);
269  self::expectExceptionCode(1550060977);
270 
271  if ($mimeType !== null) {
272  $this->‪simulateNextFileInfoInvocation($mimeType);
273  }
274 
275  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
276  ‪ImageMagickFile::fromFilePath($filePath, null);
277  }
278 
283  {
284  return [
285  'file.ps' => ['file.ps'],
286  'file.eps' => ['file.eps'],
287  ];
288  }
289 
296  public function ‪fileStatementIsDeniedForConfiguredMimeType(string $fileName)
297  {
298  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['ps'] = 'image/x-see-no-evil';
299  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['eps'] = 'image/x-see-no-evil';
300 
301  self::expectException(Exception::class);
302  self::expectExceptionCode(1550060977);
303 
304  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
305  ‪ImageMagickFile::fromFilePath($filePath, null);
306  }
307 
313  private function ‪addFiles(array &$structure, array $fileNames, string $sourcePath): void
314  {
315  $structure = array_merge(
316  $structure,
317  array_fill_keys(
318  $fileNames,
319  file_get_contents($sourcePath)
320  )
321  );
322  }
323 
328  private function ‪substituteVariables(string $value): string
329  {
330  return str_replace(
331  ['{directory}'],
332  [$this->directory->url()],
333  $value
334  );
335  }
336 
341  private function ‪simulateNextFileInfoInvocation(string $mimeType, array $mimeExtensions = [])
342  {
344  $fileInfo = $this->getAccessibleMock(
345  FileInfo::class,
346  ['getMimeType', 'getMimeExtensions'],
347  [],
348  '',
349  false
350  );
351  $fileInfo->expects(self::atLeastOnce())->method('getMimeType')->willReturn($mimeType);
352  $fileInfo->expects(self::atLeastOnce())->method('getMimeExtensions')->willReturn($mimeExtensions);
353  GeneralUtility::addInstance(FileInfo::class, $fileInfo);
354  }
355 }
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedForConfiguredMimeType
‪fileStatementIsResolvedForConfiguredMimeType(string $fileName, string $expectation)
Definition: ImageMagickFileTest.php:230
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\resultIsEscaped
‪resultIsEscaped(string $fileName, ?int $frame, string $expectation)
Definition: ImageMagickFileTest.php:118
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedForEnforcedMimeTypeDataProvider
‪array fileStatementIsResolvedForEnforcedMimeTypeDataProvider()
Definition: ImageMagickFileTest.php:175
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedForEnforcedMimeType
‪fileStatementIsResolvedForEnforcedMimeType(string $fileName, string $expectation, string $mimeType)
Definition: ImageMagickFileTest.php:203
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\framesAreConsideredDataProvider
‪array framesAreConsideredDataProvider()
Definition: ImageMagickFileTest.php:65
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\$directory
‪vfsStreamDirectory $directory
Definition: ImageMagickFileTest.php:33
‪TYPO3\CMS\Core\Exception
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsDenied
‪fileStatementIsDenied(string $fileName, string $mimeType=null)
Definition: ImageMagickFileTest.php:265
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedDataProvider
‪array fileStatementIsResolvedDataProvider()
Definition: ImageMagickFileTest.php:129
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedForConfiguredMimeTypeDataProvider
‪array fileStatementIsResolvedForConfiguredMimeTypeDataProvider()
Definition: ImageMagickFileTest.php:215
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsDeniedForConfiguredMimeType
‪fileStatementIsDeniedForConfiguredMimeType(string $fileName)
Definition: ImageMagickFileTest.php:295
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\tearDown
‪tearDown()
Definition: ImageMagickFileTest.php:56
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolved
‪fileStatementIsResolved(string $fileName, string $expectation)
Definition: ImageMagickFileTest.php:161
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\addFiles
‪addFiles(array &$structure, array $fileNames, string $sourcePath)
Definition: ImageMagickFileTest.php:312
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\framesAreConsidered
‪framesAreConsidered(string $fileName, ?int $frame, string $expectation)
Definition: ImageMagickFileTest.php:81
‪TYPO3\CMS\Core\Tests\Functional\Imaging
Definition: ImageMagickFileTest.php:18
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\substituteVariables
‪string substituteVariables(string $value)
Definition: ImageMagickFileTest.php:327
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\resultIsEscapedDataProvider
‪array resultIsEscapedDataProvider()
Definition: ImageMagickFileTest.php:92
‪TYPO3\CMS\Core\Imaging\ImageMagickFile\fromFilePath
‪static ImageMagickFile fromFilePath(string $filePath, int $frame=null)
Definition: ImageMagickFile.php:113
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsDeniedDataProvider
‪array fileStatementIsDeniedDataProvider()
Definition: ImageMagickFileTest.php:246
‪TYPO3\CMS\Core\Imaging\ImageMagickFile
Definition: ImageMagickFile.php:30
‪TYPO3\CMS\Core\Type\File\FileInfo
Definition: FileInfo.php:25
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsDeniedForConfiguredMimeTypeDataProvider
‪array fileStatementIsDeniedForConfiguredMimeTypeDataProvider()
Definition: ImageMagickFileTest.php:281
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest
Definition: ImageMagickFileTest.php:30
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\simulateNextFileInfoInvocation
‪simulateNextFileInfoInvocation(string $mimeType, array $mimeExtensions=[])
Definition: ImageMagickFileTest.php:340
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\setUp
‪setUp()
Definition: ImageMagickFileTest.php:35