‪TYPO3CMS  10.4
ZipServiceTest.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;
25 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
26 
27 class ‪ZipServiceTest extends FunctionalTestCase
28 {
32  private ‪$vfs;
33 
37  private ‪$directory;
38 
39  protected function ‪setUp(): void
40  {
41  parent::setUp();
42 
43  $structure = [
44  'typo3conf' => [
45  'ext' => [],
46  ],
47  ];
48  $this->vfs = vfsStream::setup('root', null, $structure);
49  $this->directory = vfsStream::url('root/typo3conf/ext');
50  }
51 
52  protected function ‪tearDown(): void
53  {
54  parent::tearDown();
55  unset($this->vfs, $this->directory);
56  }
57 
62  {
63  $extensionDirectory = $this->directory . '/malicious';
64  ‪GeneralUtility::mkdir($extensionDirectory);
65 
66  (new ZipService())->extract(
67  __DIR__ . '/Fixtures/malicious.zip',
68  $extensionDirectory
69  );
70  self::assertFileNotExists($extensionDirectory . '/../tool.php');
71  self::assertFileExists($extensionDirectory . '/tool.php');
72  // This is a smoke test to verify PHP's zip library is broken regarding symlinks
73  self::assertFileExists($extensionDirectory . '/passwd');
74  self::assertFalse(is_link($extensionDirectory . '/passwd'));
75  }
76 
80  public function ‪fileContentIsExtractedAsExpected(): void
81  {
82  $extensionDirectory = $this->directory . '/my_extension';
83  ‪GeneralUtility::mkdir($extensionDirectory);
84 
85  (new ZipService())->extract(
86  __DIR__ . '/Fixtures/my_extension.zip',
87  $extensionDirectory
88  );
89 
90  self::assertDirectoryExists($extensionDirectory . '/Classes');
91  self::assertFileExists($extensionDirectory . '/Resources/Public/Css/empty.css');
92  self::assertFileExists($extensionDirectory . '/ext_emconf.php');
93  }
94 
99  {
100  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'] = '0777';
101  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask'] = '0772';
102  $extensionDirectory = $this->directory . '/my_extension';
103  ‪GeneralUtility::mkdir($extensionDirectory);
104 
105  (new ZipService())->extract(
106  __DIR__ . '/Fixtures/my_extension.zip',
107  $extensionDirectory
108  );
109 
110  self::assertDirectoryExists($extensionDirectory . '/Classes');
111  self::assertFileExists($extensionDirectory . '/Resources/Public/Css/empty.css');
112  self::assertFileExists($extensionDirectory . '/ext_emconf.php');
113 
114  $filePerms = fileperms($extensionDirectory . '/Resources/Public/Css/empty.css');
115  $folderPerms = fileperms($extensionDirectory . '/Classes');
116  self::assertEquals(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'], substr(sprintf('%o', $filePerms), -4));
117  self::assertEquals(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask'], substr(sprintf('%o', $folderPerms), -4));
118  }
119 
123  public function ‪nonExistentFileThrowsException(): void
124  {
125  $this->expectException(ExtractException::class);
126  $this->expectExceptionCode(1565709712);
127 
128  (new ZipService())->extract(
129  'foobar.zip',
130  vfsStream::url('root')
131  );
132  }
133 
137  public function ‪nonExistentDirectoryThrowsException(): void
138  {
139  $this->expectException(\RuntimeException::class);
140  $this->expectExceptionCode(1565773005);
141 
142  (new ZipService())->extract(
143  __DIR__ . '/Fixtures/my_extension.zip',
144  vfsStream::url('root/non-existent-directory')
145  );
146  }
147 
151  public function ‪nonWritableDirectoryThrowsException(): void
152  {
153  $this->expectException(\RuntimeException::class);
154  $this->expectExceptionCode(1565773006);
155 
156  $extensionDirectory = $this->directory . '/my_extension';
157  ‪GeneralUtility::mkdir($extensionDirectory);
158  chmod($extensionDirectory, 0000);
159 
160  (new ZipService())->extract(
161  __DIR__ . '/Fixtures/my_extension.zip',
162  $extensionDirectory
163  );
164  self::assertFileExists($extensionDirectory . '/Resources/Public/Css/empty.css');
165  }
166 
170  public function ‪verifyDetectsValidArchive(): void
171  {
172  self::assertTrue(
173  (new ZipService())->verify(__DIR__ . '/Fixtures/my_extension.zip')
174  );
175  }
176 
180  public function ‪verifyDetectsSuspiciousSequences(): void
181  {
182  $this->expectException(ExtractException::class);
183  $this->expectExceptionCode(1565709714);
184 
185  (new ZipService())->verify(__DIR__ . '/Fixtures/malicious.zip');
186  }
187 }
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\$vfs
‪vfsStreamDirectory $vfs
Definition: ZipServiceTest.php:31
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive
Definition: ZipServiceTest.php:18
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\tearDown
‪tearDown()
Definition: ZipServiceTest.php:50
‪TYPO3\CMS\Core\Exception\Archive\ExtractException
Definition: ExtractException.php:26
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\nonWritableDirectoryThrowsException
‪nonWritableDirectoryThrowsException()
Definition: ZipServiceTest.php:149
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\$directory
‪string $directory
Definition: ZipServiceTest.php:35
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\setUp
‪setUp()
Definition: ZipServiceTest.php:37
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\fileContentIsExtractedAsExpected
‪fileContentIsExtractedAsExpected()
Definition: ZipServiceTest.php:78
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\nonExistentFileThrowsException
‪nonExistentFileThrowsException()
Definition: ZipServiceTest.php:121
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\nonExistentDirectoryThrowsException
‪nonExistentDirectoryThrowsException()
Definition: ZipServiceTest.php:135
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\fileContentIsExtractedAsExpectedAndSetsPermissions
‪fileContentIsExtractedAsExpectedAndSetsPermissions()
Definition: ZipServiceTest.php:96
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest
Definition: ZipServiceTest.php:28
‪TYPO3\CMS\Core\Service\Archive\ZipService
Definition: ZipService.php:29
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\verifyDetectsValidArchive
‪verifyDetectsValidArchive()
Definition: ZipServiceTest.php:168
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\verifyDetectsSuspiciousSequences
‪verifyDetectsSuspiciousSequences()
Definition: ZipServiceTest.php:178
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir
‪static bool mkdir($newFolder)
Definition: GeneralUtility.php:2005
‪TYPO3\CMS\Core\Tests\Functional\Service\Archive\ZipServiceTest\filesCanNotGetExtractedOutsideTargetDirectory
‪filesCanNotGetExtractedOutsideTargetDirectory()
Definition: ZipServiceTest.php:59