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