‪TYPO3CMS  9.5
ImageMagickFileTest.php
Go to the documentation of this file.
1 <?php
2 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 
18 use org\bovigo\vfs\vfsStream;
19 use org\bovigo\vfs\vfsStreamDirectory;
20 use PHPUnit\Framework\MockObject\MockObject;
25 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
26 
27 class ‪ImageMagickFileTest extends FunctionalTestCase
28 {
32  private ‪$directory;
33 
34  protected function ‪setUp()
35  {
36  parent::setUp();
37 
38  $fixturePath = __DIR__ . '/Fixtures';
39  $structure = [];
40  $this->‪addFiles($structure, ['file.ai', 'file.ai.jpg'], $fixturePath . '/file.ai');
41  $this->‪addFiles($structure, ['file.bmp', 'file.bmp.jpg'], $fixturePath . '/file.bmp');
42  $this->‪addFiles($structure, ['file.gif', 'file.gif.jpg'], $fixturePath . '/file.gif');
43  $this->‪addFiles($structure, ['file.fax', 'file.fax.jpg'], $fixturePath . '/file.fax');
44  $this->‪addFiles($structure, ['file.jpg', 'file.jpg.png'], $fixturePath . '/file.jpg');
45  $this->‪addFiles($structure, ['file.png', 'file.png.jpg'], $fixturePath . '/file.png');
46  $this->‪addFiles($structure, ['file.svg', 'file.svg.jpg'], $fixturePath . '/file.svg');
47  $this->‪addFiles($structure, ['file.tif', 'file.tif.jpg'], $fixturePath . '/file.tif');
48  $this->‪addFiles($structure, ['file.webp', 'file.webp.jpg'], $fixturePath . '/file.webp');
49  $this->‪addFiles($structure, ['file.pdf', 'file.pdf.jpg'], $fixturePath . '/file.pdf');
50  $this->‪addFiles($structure, ['file.ps', 'file.ps.jpg'], $fixturePath . '/file.ps');
51  $this->‪addFiles($structure, ['file.eps', 'file.eps.jpg'], $fixturePath . '/file.eps');
52  $this->directory = vfsStream::setup('root', null, $structure);
53  }
54 
55  protected function ‪tearDown()
56  {
57  unset($this->directory);
58  parent::tearDown();
59  }
60 
64  public function ‪framesAreConsideredDataProvider(): array
65  {
66  return [
67  'file.pdf' => ['file.pdf', null, '\'pdf:{directory}/file.pdf\''],
68  'file.pdf[0]' => ['file.pdf', 0, '\'pdf:{directory}/file.pdf[0]\''],
69  ];
70  }
71 
80  public function ‪framesAreConsidered(string $fileName, ?int $frame, string $expectation)
81  {
82  $expectation = $this->‪substituteVariables($expectation);
83  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
84  $file = ‪ImageMagickFile::fromFilePath($filePath, $frame);
85  self::assertSame($expectation, (string)$file);
86  }
87 
91  public function ‪resultIsEscapedDataProvider(): array
92  {
93  // probably Windows system
94  if (DIRECTORY_SEPARATOR === '\\') {
95  return [
96  'without frame' => ['file.pdf', null, '"pdf:{directory}/file.pdf"'],
97  'with first frame' => ['file.pdf', 0, '"pdf:{directory}/file.pdf[0]"'],
98  'special literals' => ['\'`%$!".png', 0, '"png:{directory}/\'` $ .png[0]"'],
99  ];
100  }
101  // probably Unix system
102  return [
103  'without frame' => ['file.pdf', null, '\'pdf:{directory}/file.pdf\''],
104  'with first frame' => ['file.pdf', 0, '\'pdf:{directory}/file.pdf[0]\''],
105  'special literals' => ['\'`%$!".png', 0, '\'png:{directory}/\'\\\'\'`%$!".png[0]\''],
106  ];
107  }
108 
117  public function ‪resultIsEscaped(string $fileName, ?int $frame, string $expectation)
118  {
119  $expectation = $this->‪substituteVariables($expectation);
120  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
121  $file = ‪ImageMagickFile::fromFilePath($filePath, $frame);
122  self::assertSame($expectation, (string)$file);
123  }
124 
128  public function ‪fileStatementIsResolvedDataProvider(): array
129  {
130  return [
131  'file.ai' => ['file.ai', '\'pdf:{directory}/file.ai\''],
132  'file.ai.jpg' => ['file.ai.jpg', '\'pdf:{directory}/file.ai.jpg\''],
133  'file.gif' => ['file.gif', '\'gif:{directory}/file.gif\''],
134  'file.gif.jpg' => ['file.gif.jpg', '\'gif:{directory}/file.gif.jpg\''],
135  'file.jpg' => ['file.jpg', '\'jpg:{directory}/file.jpg\''],
136  'file.jpg.png' => ['file.jpg.png', '\'jpg:{directory}/file.jpg.png\''],
137  'file.png' => ['file.png', '\'png:{directory}/file.png\''],
138  'file.png.jpg' => ['file.png.jpg', '\'png:{directory}/file.png.jpg\''],
139  'file.svg' => ['file.svg', '\'svg:{directory}/file.svg\''],
140  'file.svg.jpg' => ['file.svg.jpg', '\'svg:{directory}/file.svg.jpg\''],
141  'file.tif' => ['file.tif', '\'tif:{directory}/file.tif\''],
142  'file.tif.jpg' => ['file.tif.jpg', '\'tif:{directory}/file.tif.jpg\''],
143  'file.webp' => ['file.webp', '\'webp:{directory}/file.webp\''],
144  'file.webp.jpg' => ['file.webp.jpg', '\'webp:{directory}/file.webp.jpg\''],
145  'file.pdf' => ['file.pdf', '\'pdf:{directory}/file.pdf\''],
146  'file.pdf.jpg' => ['file.pdf.jpg', '\'pdf:{directory}/file.pdf.jpg\''],
147  // accepted, since postscript files are converted using 'jpg:' format
148  'file.ps.jpg' => ['file.ps.jpg', '\'jpg:{directory}/file.ps.jpg\''],
149  'file.eps.jpg' => ['file.eps.jpg', '\'jpg:{directory}/file.eps.jpg\''],
150  ];
151  }
152 
160  public function ‪fileStatementIsResolved(string $fileName, string $expectation)
161  {
162  $expectation = $this->‪substituteVariables($expectation);
163  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
164  $file = ‪ImageMagickFile::fromFilePath($filePath, null);
165  self::assertSame($expectation, (string)$file);
166  }
167 
175  {
176  return [
177  'file.ai.jpg' => ['file.ai.jpg', '\'jpg:{directory}/file.ai.jpg\'', 'inode/x-empty'],
178  'file.bmp.jpg' => ['file.bmp.jpg', '\'jpg:{directory}/file.bmp.jpg\'', 'inode/x-empty'],
179  'file.fax.jpg' => ['file.fax.jpg', '\'jpg:{directory}/file.fax.jpg\'', 'inode/x-empty'],
180  'file.gif.jpg' => ['file.gif.jpg', '\'jpg:{directory}/file.gif.jpg\'', 'inode/x-empty'],
181  'file.jpg' => ['file.jpg', '\'jpg:{directory}/file.jpg\'', 'inode/x-empty'],
182  'file.jpg.png' => ['file.jpg.png', '\'png:{directory}/file.jpg.png\'', 'inode/x-empty'],
183  'file.png' => ['file.png', '\'png:{directory}/file.png\'', 'inode/x-empty'],
184  'file.png.jpg' => ['file.png.jpg', '\'jpg:{directory}/file.png.jpg\'', 'inode/x-empty'],
185  'file.svg.jpg' => ['file.svg.jpg', '\'jpg:{directory}/file.svg.jpg\'', 'inode/x-empty'],
186  'file.tif' => ['file.tif', '\'tif:{directory}/file.tif\'', 'inode/x-empty'],
187  'file.tif.jpg' => ['file.tif.jpg', '\'jpg:{directory}/file.tif.jpg\'', 'inode/x-empty'],
188  'file.webp' => ['file.webp', '\'webp:{directory}/file.webp\'', 'inode/x-empty'],
189  'file.webp.jpg' => ['file.webp.jpg', '\'jpg:{directory}/file.webp.jpg\'', 'inode/x-empty'],
190  'file.pdf.jpg' => ['file.pdf.jpg', '\'jpg:{directory}/file.pdf.jpg\'', 'inode/x-empty'],
191  ];
192  }
193 
202  public function ‪fileStatementIsResolvedForEnforcedMimeType(string $fileName, string $expectation, string $mimeType)
203  {
204  $this->‪simulateNextFileInfoInvocation($mimeType);
205  $expectation = $this->‪substituteVariables($expectation);
206  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
207  $file = ‪ImageMagickFile::fromFilePath($filePath, null);
208  self::assertSame($expectation, (string)$file);
209  }
210 
215  {
216  return [
217  'file.fax' => ['file.fax', '\'g3:{directory}/file.fax\''],
218  'file.bmp' => ['file.bmp', '\'dib:{directory}/file.bmp\''],
219  ];
220  }
221 
229  public function ‪fileStatementIsResolvedForConfiguredMimeType(string $fileName, string $expectation)
230  {
231  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['g3'] = 'image/g3fax';
232  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['fax'] = 'image/g3fax';
233  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['dib'] = 'image/x-ms-bmp';
234  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['bmp'] = 'image/x-ms-bmp';
235 
236  $expectation = $this->‪substituteVariables($expectation);
237  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
238  $file = ‪ImageMagickFile::fromFilePath($filePath, null);
239  self::assertSame($expectation, (string)$file);
240  }
241 
245  public function ‪fileStatementIsDeniedDataProvider(): array
246  {
247  return [
248  'file.ps' => ['file.ps'],
249  'file.eps' => ['file.eps'],
250  // denied since not defined in allowed extensions
251  'file.ai' => ['file.ai', 'inode/x-empty'],
252  'file.svg' => ['file.svg', 'inode/x-empty'],
253  'file.pdf' => ['file.pdf', 'inode/x-empty'],
254  ];
255  }
256 
264  public function ‪fileStatementIsDenied(string $fileName, string $mimeType = null)
265  {
266  self::expectException(Exception::class);
267  self::expectExceptionCode(1550060977);
268 
269  if ($mimeType !== null) {
270  $this->‪simulateNextFileInfoInvocation($mimeType);
271  }
272 
273  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
274  ‪ImageMagickFile::fromFilePath($filePath, null);
275  }
276 
281  {
282  return [
283  'file.ps' => ['file.ps'],
284  'file.eps' => ['file.eps'],
285  ];
286  }
287 
294  public function ‪fileStatementIsDeniedForConfiguredMimeType(string $fileName)
295  {
296  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['ps'] = 'image/x-see-no-evil';
297  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['eps'] = 'image/x-see-no-evil';
298 
299  self::expectException(Exception::class);
300  self::expectExceptionCode(1550060977);
301 
302  $filePath = sprintf('%s/%s', $this->directory->url(), $fileName);
303  ‪ImageMagickFile::fromFilePath($filePath, null);
304  }
305 
311  private function ‪addFiles(array &$structure, array $fileNames, string $sourcePath): void
312  {
313  $structure = array_merge(
314  $structure,
315  array_fill_keys(
316  $fileNames,
317  file_get_contents($sourcePath)
318  )
319  );
320  }
321 
326  private function ‪substituteVariables(string $value): string
327  {
328  return str_replace(
329  ['{directory}'],
330  [$this->directory->url()],
331  $value
332  );
333  }
334 
339  private function ‪simulateNextFileInfoInvocation(string $mimeType, array $mimeExtensions = [])
340  {
342  $fileInfo = $this->getAccessibleMock(
343  FileInfo::class,
344  ['getMimeType', 'getMimeExtensions'],
345  [],
346  '',
347  false
348  );
349  $fileInfo->expects(self::atLeastOnce())->method('getMimeType')->willReturn($mimeType);
350  $fileInfo->expects(self::atLeastOnce())->method('getMimeExtensions')->willReturn($mimeExtensions);
351  GeneralUtility::addInstance(FileInfo::class, $fileInfo);
352  }
353 }
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedForConfiguredMimeType
‪fileStatementIsResolvedForConfiguredMimeType(string $fileName, string $expectation)
Definition: ImageMagickFileTest.php:228
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\resultIsEscaped
‪resultIsEscaped(string $fileName, ?int $frame, string $expectation)
Definition: ImageMagickFileTest.php:116
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedForEnforcedMimeTypeDataProvider
‪array fileStatementIsResolvedForEnforcedMimeTypeDataProvider()
Definition: ImageMagickFileTest.php:173
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedForEnforcedMimeType
‪fileStatementIsResolvedForEnforcedMimeType(string $fileName, string $expectation, string $mimeType)
Definition: ImageMagickFileTest.php:201
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\framesAreConsideredDataProvider
‪array framesAreConsideredDataProvider()
Definition: ImageMagickFileTest.php:63
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\$directory
‪vfsStreamDirectory $directory
Definition: ImageMagickFileTest.php:31
‪TYPO3\CMS\Core\Exception
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsDenied
‪fileStatementIsDenied(string $fileName, string $mimeType=null)
Definition: ImageMagickFileTest.php:263
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedDataProvider
‪array fileStatementIsResolvedDataProvider()
Definition: ImageMagickFileTest.php:127
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolvedForConfiguredMimeTypeDataProvider
‪array fileStatementIsResolvedForConfiguredMimeTypeDataProvider()
Definition: ImageMagickFileTest.php:213
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsDeniedForConfiguredMimeType
‪fileStatementIsDeniedForConfiguredMimeType(string $fileName)
Definition: ImageMagickFileTest.php:293
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\tearDown
‪tearDown()
Definition: ImageMagickFileTest.php:54
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsResolved
‪fileStatementIsResolved(string $fileName, string $expectation)
Definition: ImageMagickFileTest.php:159
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\addFiles
‪addFiles(array &$structure, array $fileNames, string $sourcePath)
Definition: ImageMagickFileTest.php:310
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\framesAreConsidered
‪framesAreConsidered(string $fileName, ?int $frame, string $expectation)
Definition: ImageMagickFileTest.php:79
‪TYPO3\CMS\Core\Tests\Functional\Imaging
Definition: ImageMagickFileTest.php:3
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\substituteVariables
‪string substituteVariables(string $value)
Definition: ImageMagickFileTest.php:325
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\resultIsEscapedDataProvider
‪array resultIsEscapedDataProvider()
Definition: ImageMagickFileTest.php:90
‪TYPO3\CMS\Core\Imaging\ImageMagickFile\fromFilePath
‪static ImageMagickFile fromFilePath(string $filePath, int $frame=null)
Definition: ImageMagickFile.php:111
‪$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:244
‪TYPO3\CMS\Core\Imaging\ImageMagickFile
Definition: ImageMagickFile.php:28
‪TYPO3\CMS\Core\Type\File\FileInfo
Definition: FileInfo.php:24
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\fileStatementIsDeniedForConfiguredMimeTypeDataProvider
‪array fileStatementIsDeniedForConfiguredMimeTypeDataProvider()
Definition: ImageMagickFileTest.php:279
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest
Definition: ImageMagickFileTest.php:28
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\simulateNextFileInfoInvocation
‪simulateNextFileInfoInvocation(string $mimeType, array $mimeExtensions=[])
Definition: ImageMagickFileTest.php:338
‪TYPO3\CMS\Core\Tests\Functional\Imaging\ImageMagickFileTest\setUp
‪setUp()
Definition: ImageMagickFileTest.php:33