‪TYPO3CMS  11.5
ZipService.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 
22 
29 {
38  public function ‪extract(string $fileName, string $directory): bool
39  {
40  $this->‪assertDirectoryIsWritable($directory);
41 
42  $zip = new \ZipArchive();
43  $state = $zip->open($fileName);
44  if ($state !== true) {
45  throw new ‪ExtractException(
46  sprintf('Unable to open zip file %s, error code %d', $fileName, $state),
47  1565709712
48  );
49  }
50 
51  $result = $zip->extractTo($directory);
52  $zip->close();
53  if ($result) {
54  ‪GeneralUtility::fixPermissions(rtrim($directory, '/'), true);
55  }
56  return $result;
57  }
58 
64  public function ‪verify(string $fileName): bool
65  {
66  $zip = new \ZipArchive();
67  $state = $zip->open($fileName);
68  if ($state !== true) {
69  throw new ‪ExtractException(
70  sprintf('Unable to open zip file %s, error code %d', $fileName, $state),
71  1565709713
72  );
73  }
74 
75  for ($i = 0; $i < $zip->numFiles; $i++) {
76  $entryName = (string)$zip->getNameIndex($i);
77  if (preg_match('#/(?:\.{2,})+#', $entryName) // Contains any traversal sequence starting with a slash, e.g. /../, /.., /.../
78  || preg_match('#^(?:\.{2,})+/#', $entryName) // Starts with a traversal sequence, e.g. ../, .../
79  ) {
80  throw new ‪ExtractException(
81  sprintf('Suspicious sequence in zip file %s: %s', $fileName, $entryName),
82  1565709714
83  );
84  }
85  }
86 
87  $zip->close();
88  return true;
89  }
90 
94  private function ‪assertDirectoryIsWritable(string $directory): void
95  {
96  if (!is_dir($directory)) {
97  throw new \RuntimeException(
98  sprintf('Directory %s does not exist', $directory),
99  1565773005
100  );
101  }
102  if (!is_writable($directory)) {
103  throw new \RuntimeException(
104  sprintf('Directory %s is not writable', $directory),
105  1565773006
106  );
107  }
108  }
109 }
‪TYPO3\CMS\Core\Service\Archive
Definition: ZipService.php:18
‪TYPO3\CMS\Core\Exception\Archive\ExtractException
Definition: ExtractException.php:25
‪TYPO3\CMS\Core\Service\Archive\ZipService\assertDirectoryIsWritable
‪assertDirectoryIsWritable(string $directory)
Definition: ZipService.php:94
‪TYPO3\CMS\Core\Service\Archive\ZipService\verify
‪bool verify(string $fileName)
Definition: ZipService.php:64
‪TYPO3\CMS\Core\Service\Archive\ZipService\extract
‪bool extract(string $fileName, string $directory)
Definition: ZipService.php:38
‪TYPO3\CMS\Core\Utility\GeneralUtility\fixPermissions
‪static mixed fixPermissions($path, $recursive=false)
Definition: GeneralUtility.php:1749
‪TYPO3\CMS\Core\Service\Archive\ZipService
Definition: ZipService.php:29
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50