‪TYPO3CMS  9.5
BasicFileUtility.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
20 
32 {
36  const ‪UNSAFE_FILENAME_CHARACTER_EXPRESSION = '\\x00-\\x2C\\/\\x3A-\\x3F\\x5B-\\x60\\x7B-\\xBF';
37 
43  public ‪$maxNumber = 99;
44 
50  public ‪$uniquePrecision = 6;
51 
56  protected ‪$fileExtensionPermissions = [
57  'allow' => '*',
58  'deny' => PHP_EXTENSIONS_DEFAULT
59 
60  ];
61 
62  /**********************************
63  *
64  * Checking functions
65  *
66  **********************************/
67 
74  public function ‪setFileExtensionPermissions($allowedFilePermissions, $deniedFilePermissions)
75  {
76  $this->fileExtensionPermissions['allow'] = GeneralUtility::uniqueList(strtolower($allowedFilePermissions));
77  $this->fileExtensionPermissions['deny'] = GeneralUtility::uniqueList(strtolower($deniedFilePermissions));
78  }
79 
86  protected function ‪is_allowed($fileExtension)
87  {
88  $fileExtension = strtolower($fileExtension);
89  if ($fileExtension) {
90  // If the extension is found amongst the allowed types, we return TRUE immediately
91  if ($this->fileExtensionPermissions['allow'] === '*' || GeneralUtility::inList($this->fileExtensionPermissions['allow'], $fileExtension)) {
92  return true;
93  }
94  // If the extension is found amongst the denied types, we return FALSE immediately
95  if ($this->fileExtensionPermissions['deny'] === '*' || GeneralUtility::inList($this->fileExtensionPermissions['deny'], $fileExtension)) {
96  return false;
97  }
98  } else {
99  // If no extension
100  if ($this->fileExtensionPermissions['allow'] === '*') {
101  return true;
102  }
103  if ($this->fileExtensionPermissions['deny'] === '*') {
104  return false;
105  }
106  }
107  // If no match we return TRUE
108  return true;
109  }
110 
122  public function ‪checkIfAllowed($ext, $_, $filename = '')
123  {
124  return GeneralUtility::verifyFilenameAgainstDenyPattern($filename) && $this->‪is_allowed($ext);
125  }
126 
133  protected function ‪is_directory($theDir)
134  {
135  // @todo: should go into the LocalDriver in a protected way (not important to the outside world)
136  if (GeneralUtility::validPathStr($theDir)) {
137  $theDir = ‪PathUtility::getCanonicalPath($theDir);
138  if (@is_dir($theDir)) {
139  return $theDir;
140  }
141  }
142  return false;
143  }
144 
158  public function ‪getUniqueName($theFile, $theDest, $dontCheckForUnique = false)
159  {
160  // @todo: should go into the LocalDriver in a protected way (not important to the outside world)
161  $theDest = $this->‪is_directory($theDest);
162  // $theDest is cleaned up
163  $origFileInfo = GeneralUtility::split_fileref($theFile);
164  // Fetches info about path, name, extension of $theFile
165  if ($theDest) {
166  // Check if the file exists and if not - return the filename...
167  $fileInfo = $origFileInfo;
168  $theDestFile = $theDest . '/' . $fileInfo['file'];
169  // The destinations file
170  if (!file_exists($theDestFile) || $dontCheckForUnique) {
171  // If the file does NOT exist we return this filename
172  return $theDestFile;
173  }
174  // Well the filename in its pure form existed. Now we try to append numbers / unique-strings and see if we can find an available filename...
175  $theTempFileBody = preg_replace('/_[0-9][0-9]$/', '', $origFileInfo['filebody']);
176  // This removes _xx if appended to the file
177  $theOrigExt = $origFileInfo['realFileext'] ? '.' . $origFileInfo['realFileext'] : '';
178  for ($a = 1; $a <= $this->maxNumber + 1; $a++) {
179  if ($a <= $this->maxNumber) {
180  // First we try to append numbers
181  $insert = '_' . sprintf('%02d', $a);
182  } else {
183  // .. then we try unique-strings...
184  $insert = '_' . substr(md5(uniqid('', true)), 0, $this->uniquePrecision);
185  }
186  $theTestFile = $theTempFileBody . $insert . $theOrigExt;
187  $theDestFile = $theDest . '/' . $theTestFile;
188  // The destinations file
189  if (!file_exists($theDestFile)) {
190  // If the file does NOT exist we return this filename
191  return $theDestFile;
192  }
193  }
194  }
195  }
196 
197  /*********************
198  *
199  * Cleaning functions
200  *
201  *********************/
202 
212  public function ‪cleanFileName($fileName)
213  {
214  // Handle UTF-8 characters
215  if (‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
216  // allow ".", "-", 0-9, a-z, A-Z and everything beyond U+C0 (latin capital letter a with grave)
217  $cleanFileName = preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . ']/u', '_', trim($fileName));
218  } else {
219  $fileName = GeneralUtility::makeInstance(CharsetConverter::class)->utf8_char_mapping($fileName);
220  // Replace unwanted characters by underscores
221  $cleanFileName = preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . '\\xC0-\\xFF]/', '_', trim($fileName));
222  }
223  // Strip trailing dots and return
224  return rtrim($cleanFileName, '.');
225  }
226 }
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:23
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility
Definition: BasicFileUtility.php:32
‪TYPO3\CMS\Core\Charset\CharsetConverter
Definition: CharsetConverter.php:54
‪TYPO3\CMS\Core\Utility\PathUtility\getCanonicalPath
‪static string getCanonicalPath($path)
Definition: PathUtility.php:306
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\setFileExtensionPermissions
‪setFileExtensionPermissions($allowedFilePermissions, $deniedFilePermissions)
Definition: BasicFileUtility.php:71
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\getUniqueName
‪string getUniqueName($theFile, $theDest, $dontCheckForUnique=false)
Definition: BasicFileUtility.php:155
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\cleanFileName
‪string cleanFileName($fileName)
Definition: BasicFileUtility.php:209
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\checkIfAllowed
‪bool checkIfAllowed($ext, $_, $filename='')
Definition: BasicFileUtility.php:119
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\UNSAFE_FILENAME_CHARACTER_EXPRESSION
‪const UNSAFE_FILENAME_CHARACTER_EXPRESSION
Definition: BasicFileUtility.php:36
‪TYPO3\CMS\Core\Utility\File
Definition: BasicFileUtility.php:2
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\is_allowed
‪bool is_allowed($fileExtension)
Definition: BasicFileUtility.php:83
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\$maxNumber
‪int $maxNumber
Definition: BasicFileUtility.php:42
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\is_directory
‪bool string is_directory($theDir)
Definition: BasicFileUtility.php:130
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\$uniquePrecision
‪int $uniquePrecision
Definition: BasicFileUtility.php:48
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\$fileExtensionPermissions
‪array $fileExtensionPermissions
Definition: BasicFileUtility.php:53