‪TYPO3CMS  11.5
PathUtilityTest.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 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
23 
28 class ‪PathUtilityTest extends UnitTestCase
29 {
34  protected ‪$backupEnvironment = true;
35 
42  public function ‪isCommonPrefixResolvedCorrectly(array $paths, $expected): void
43  {
44  $commonPrefix = ‪PathUtility::getCommonPrefix($paths);
45  self::assertEquals($expected, $commonPrefix);
46  }
47 
51  public function ‪isCommonPrefixResolvedCorrectlyDataProvider(): array
52  {
53  return [
54  [
55  [
56  '/var/www/myhost.com/t3lib/',
57  ],
58  '/var/www/myhost.com/t3lib/',
59  ],
60  [
61  [
62  '/var/www/myhost.com/t3lib/',
63  '/var/www/myhost.com/t3lib/',
64  ],
65  '/var/www/myhost.com/t3lib/',
66  ],
67  [
68  [
69  '/var/www/myhost.com/typo3/',
70  '/var/www/myhost.com/t3lib/',
71  ],
72  '/var/www/myhost.com/',
73  ],
74  [
75  [
76  '/var/www/myhost.com/typo3/',
77  '/var/www/myhost.com/typo3',
78  ],
79  '/var/www/myhost.com/typo3/',
80  ],
81  [
82  [
83  '/var/www/myhost.com/typo3',
84  '/var/www/myhost.com/typo3',
85  ],
86  '/var/www/myhost.com/typo3/',
87  ],
88  [
89  [
90  '/var/www/myhost.com/uploads/',
91  '/var/www/myhost.com/typo3/',
92  '/var/www/myhost.com/t3lib/',
93  ],
94  '/var/www/myhost.com/',
95  ],
96  [
97  [
98  '/var/www/myhost.com/uploads/directory/',
99  '/var/www/myhost.com/typo3/sysext/',
100  '/var/www/myhost.com/t3lib/utility/',
101  ],
102  '/var/www/myhost.com/',
103  ],
104  [
105  [
106  'C:\\www\\myhost.com\\t3lib\\',
107  ],
108  'C:/www/myhost.com/t3lib/',
109  ],
110  [
111  [
112  'C:\\www\\myhost.com\\t3lib\\',
113  'C:\\www\\myhost.com\\t3lib\\',
114  ],
115  'C:/www/myhost.com/t3lib/',
116  ],
117  [
118  [
119  'C:\\www\\myhost.com\\typo3\\',
120  'C:\\www\\myhost.com\\t3lib\\',
121  ],
122  'C:/www/myhost.com/',
123  ],
124  [
125  [
126  'C:\\www\\myhost.com\\uploads\\',
127  'C:\\www\\myhost.com\\typo3\\',
128  'C:\\www\\myhost.com\\t3lib\\',
129  ],
130  'C:/www/myhost.com/',
131  ],
132  [
133  [
134  'C:\\www\\myhost.com\\uploads\\directory\\',
135  'C:\\www\\myhost.com\\typo3\\sysext\\',
136  'C:\\www\\myhost.com\\t3lib\\utility\\',
137  ],
138  'C:/www/myhost.com/',
139  ],
140  ];
141  }
142 
150  public function ‪isRelativePathResolvedCorrectly($source, $target, $expected): void
151  {
152  $relativePath = ‪PathUtility::getRelativePath($source, $target);
153  self::assertEquals($expected, $relativePath);
154  }
155 
159  public function ‪isRelativePathResolvedCorrectlyDataProvider(): array
160  {
161  return [
162  [
163  '/',
164  ‪Environment::getPublicPath() . '/directory',
165  null,
166  ],
167  [
168  ‪Environment::getPublicPath() . '/t3lib/',
169  ‪Environment::getPublicPath() . '/t3lib/',
170  '',
171  ],
172  [
173  ‪Environment::getPublicPath() . '/typo3/',
174  ‪Environment::getPublicPath() . '/t3lib/',
175  '../t3lib/',
176  ],
177  [
179  ‪Environment::getPublicPath() . '/t3lib/',
180  't3lib/',
181  ],
182  [
183  ‪Environment::getPublicPath() . '/t3lib/',
184  ‪Environment::getPublicPath() . '/t3lib/stddb/',
185  'stddb/',
186  ],
187  [
188  ‪Environment::getPublicPath() . '/typo3/sysext/frontend/',
189  ‪Environment::getPublicPath() . '/t3lib/utility/',
190  '../../../t3lib/utility/',
191  ],
192  ];
193  }
194 
202  public function ‪isTrailingSeparatorSanitizedCorrectly($path, $separator, $expected): void
203  {
204  $sanitizedPath = ‪PathUtility::sanitizeTrailingSeparator($path, $separator);
205  self::assertEquals($expected, $sanitizedPath);
206  }
207 
212  {
213  return [
214  ['/var/www//', '/', '/var/www/'],
215  ['/var/www/', '/', '/var/www/'],
216  ['/var/www', '/', '/var/www/'],
217  ];
218  }
219 
226  {
227  return [
228  'basic' => [
229  '/abc/def/one.txt',
230  '../two.txt',
231  '/abc/two.txt',
232  ],
233  'same folder' => [
234  '/abc/one.txt',
235  './two.txt',
236  '/abc/two.txt',
237  ],
238  'preserve relative path if path goes above start path' => [
239  'abc/one.txt',
240  '../../two.txt',
241  '../two.txt',
242  ],
243  'preserve absolute path even if path goes above start path' => [
244  '/abc/one.txt',
245  '../../two.txt',
246  '/two.txt',
247  ],
248  'base folder with same folder path' => [
249  '/abc/',
250  './two.txt',
251  '/abc/two.txt',
252  ],
253  'base folder with parent folder path' => [
254  '/abc/bar/',
255  '../foo.txt',
256  '/abc/foo.txt',
257  ],
258  ];
259  }
260 
265  public function ‪getAbsolutePathOfRelativeReferencedFileOrPathResolvesFileCorrectly(string $baseFileName, string $includeFileName, string $expectedFileName): void
266  {
267  $resolvedFilename = ‪PathUtility::getAbsolutePathOfRelativeReferencedFileOrPath($baseFileName, $includeFileName);
268  self::assertEquals($expectedFileName, $resolvedFilename);
269  }
270 
277  {
278  return [
279  'removes single-dot-elements' => [
280  'abc/./def/././ghi',
281  'abc/def/ghi',
282  ],
283  'removes ./ at beginning' => [
284  './abc/def/ghi',
285  'abc/def/ghi',
286  ],
287  'removes double-slashes' => [
288  'abc//def/ghi',
289  'abc/def/ghi',
290  ],
291  'removes double-slashes from front, but keeps absolute path' => [
292  '//abc/def/ghi',
293  '/abc/def/ghi',
294  ],
295  'makes double-dot-elements go one level higher, test #1' => [
296  'abc/def/ghi/../..',
297  'abc',
298  ],
299  'makes double-dot-elements go one level higher, test #2' => [
300  'abc/def/ghi/../123/456/..',
301  'abc/def/123',
302  ],
303  'makes double-dot-elements go one level higher, test #3' => [
304  'abc/../../def/ghi',
305  '../def/ghi',
306  ],
307  'makes double-dot-elements go one level higher, test #4' => [
308  'abc/def/ghi//../123/456/..',
309  'abc/def/123',
310  ],
311  'truncates slash at the end' => [
312  'abc/def/ghi/',
313  'abc/def/ghi',
314  ],
315  'keeps slash in front of absolute paths' => [
316  '/abc/def/ghi',
317  '/abc/def/ghi',
318  ],
319  'keeps slash in front of absolute paths even if double-dot-elements want to go higher' => [
320  '/abc/../../def/ghi',
321  '/def/ghi',
322  ],
323  'double-dot-elements want to go higher, more than one segment' => [
324  '/abc/../../../../def/ghi',
325  '/def/ghi',
326  ],
327  'works with EXT-syntax-paths' => [
328  'EXT:abc/def/ghi/',
329  'EXT:abc/def/ghi',
330  ],
331  'truncates ending slash with space' => [
332  'abc/def/ ',
333  'abc/def',
334  ],
335  'truncates ending space' => [
336  'abc/def ',
337  'abc/def',
338  ],
339  'truncates ending dot' => [
340  'abc/def/.',
341  'abc/def',
342  ],
343  'does not truncates ending dot if part of name' => [
344  'abc/def.',
345  'abc/def.',
346  ],
347  'protocol is not removed' => [
348  'vfs://def/../text.txt',
349  'vfs://text.txt',
350  ],
351  'works with filenames' => [
352  '/def/../text.txt',
353  '/text.txt',
354  ],
355  'absolute windows path' => [
356  'C:\def\..\..\test.txt',
357  'C:/test.txt',
358  ],
359  'absolute windows path with more segments' => [
360  'C:\def\def2\def3\..\..\folder\subfolder\test.txt',
361  'C:/def/folder/subfolder/test.txt',
362  ],
363  'double slashaes' => [
364  'abc//def',
365  'abc/def',
366  ],
367  'multiple slashes' => [
368  'abc///////def',
369  'abc/def',
370  ],
371  ];
372  }
373 
380  public function ‪getCanonicalPathCorrectlyCleansPath(string $inputName, string $expectedResult): void
381  {
382  // Ensure Environment runs as Windows test
385  true,
386  false,
392  'WINDOWS'
393  );
394  self::assertSame(
395  $expectedResult,
397  );
398  }
399 
406  {
407  return [
408  'relative path' => [
409  'abc/def/ghi',
410  'abc/def',
411  ],
412  'absolute path 1' => [
413  '/var/www/html/index.php',
414  '/var/www/html',
415  ],
416  'absolute path 2' => [
417  '/var/www/html/typo3/index.php',
418  '/var/www/html/typo3',
419  ],
420  'windows path' => [
421  'C:\\inetpub\\index.php',
422  'C:\\inetpub',
423  ],
424  ];
425  }
426 
433  public function ‪dirnameDuringBootstrapCorrectlyFetchesParent(string $inputPath, string $expectedResult): void
434  {
435  self::assertSame(
436  $expectedResult,
438  );
439  }
440 
447  {
448  return [
449  'relative path' => [
450  'abc/def/ghi',
451  'ghi',
452  ],
453  'absolute path 1' => [
454  '/var/www/html/index.php',
455  'index.php',
456  ],
457  'absolute path 2' => [
458  '/var/www/html/typo3/index.php',
459  'index.php',
460  ],
461  'windows path' => [
462  'C:\\inetpub\\index.php',
463  'index.php',
464  ],
465  ];
466  }
467 
474  public function ‪basenameDuringBootstrapCorrectlyFetchesBasename(string $inputPath, string $expectedResult): void
475  {
476  self::assertSame(
477  $expectedResult,
479  );
480  }
481 
488  {
489  return [
490  'starting slash' => [
491  '/path',
492  false,
493  true,
494  ],
495  'starting slash on windows' => [
496  '/path',
497  true,
498  true,
499  ],
500  'no match' => [
501  'path',
502  false,
503  false,
504  ],
505  'no match on windows' => [
506  'path',
507  true,
508  false,
509  ],
510  'path starts with C:/' => [
511  'C:/folder',
512  false,
513  false,
514  ],
515  'path starts with C:/ on windows' => [
516  'C:/folder',
517  true,
518  true,
519  ],
520  'path starts with C:\\' => [
521  'C:\\folder',
522  false,
523  false,
524  ],
525  'path starts with C:\\ on windows' => [
526  'C:\\folder',
527  true,
528  true,
529  ],
530  'path empty' => [
531  '',
532  false,
533  false,
534  ],
535  ];
536  }
537 
545  public function ‪isAbsolutePathRespectsAllOperatingSystems(string $inputPath, bool $isWindows, bool $expectedResult): void
546  {
547  if ($isWindows) {
548  // Ensure Environment runs as Windows test
551  true,
552  false,
558  'WINDOWS'
559  );
560  }
561 
562  self::assertSame($expectedResult, ‪PathUtility::isAbsolutePath($inputPath));
563  }
564 
565  public function ‪hasProtocolAndSchemeDataProvider(): array
566  {
567  return [
568  ['//example.com/demo.html', true],
569  ['http://example.com/demo.html', true],
570  ['https://example.com/demo.html', true],
571  ['f://example.com/demo.html', true],
572  ['f:/example.com/demo.html', false],
573  ['://example.com/demo.html', false],
574  [':/example.com/demo.html', false],
575  ['/example.com/demo.html', false],
576  ['example.com/demo.html', false],
577  ['demo.html', false],
578  ['\\\\server\\unc-path\\demo.html', false],
579  ['\\\\example.com\\demo.html', false],
580  ];
581  }
582 
587  public function ‪hasProtocolAndScheme(string $url, bool $result): void
588  {
589  self::assertSame($result, ‪PathUtility::hasProtocolAndScheme($url));
590  }
591 
592  public static function ‪allowedAdditionalPathsAreEvaluatedDataProvider(): \Generator
593  {
594  // empty settings
595  yield [null, '/var/shared', false];
596  yield ['', '/var/shared', false];
597  yield [' ', '/var/shared', false];
598  yield [[], '/var/shared', false];
599  yield [[''], '/var/shared', false];
600  yield [[' '], '/var/shared', false];
601  // string settings
602  yield ['/var', '/var/shared', true];
603  yield ['/var/shared/', '/var/shared', true];
604  yield ['/var/shared', '/var/shared/', true];
605  yield ['/var/shared/', '/var/shared/', true];
606  yield ['/var/shared/', '/var/shared/file.png', true];
607  yield ['/var/shared/', '/var/shared-secret', false];
608  yield ['/var/shared/', '/var', false];
609  // array settings
610  yield [['/var'], '/var/shared', true];
611  yield [['/var/shared/'], '/var/shared', true];
612  yield [['/var/shared'], '/var/shared/', true];
613  yield [['/var/shared/'], '/var/shared/', true];
614  yield [['/var/shared/'], '/var/shared/file.png', true];
615  yield [['/var/shared/'], '/var/shared-secret', false];
616  yield [['/var/shared/'], '/var', false];
617  }
618 
625  public function ‪allowedAdditionalPathsAreEvaluated($lockRootPath, string $path, bool $expectation): void
626  {
627  ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath'] = $lockRootPath;
628  self::assertSame($expectation, ‪PathUtility::isAllowedAdditionalPath($path));
629  }
630 }
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest
Definition: PathUtilityTest.php:29
‪TYPO3\CMS\Core\Utility\PathUtility\basenameDuringBootstrap
‪static string basenameDuringBootstrap($path)
Definition: PathUtility.php:364
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\hasProtocolAndSchemeDataProvider
‪hasProtocolAndSchemeDataProvider()
Definition: PathUtilityTest.php:564
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\dirnameDuringBootstrapCorrectlyFetchesParent
‪dirnameDuringBootstrapCorrectlyFetchesParent(string $inputPath, string $expectedResult)
Definition: PathUtilityTest.php:432
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:25
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:206
‪TYPO3\CMS\Core\Utility\PathUtility\isAllowedAdditionalPath
‪static isAllowedAdditionalPath(string $path)
Definition: PathUtility.php:475
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\isTrailingSeparatorSanitizedCorrectly
‪isTrailingSeparatorSanitizedCorrectly($path, $separator, $expected)
Definition: PathUtilityTest.php:201
‪TYPO3\CMS\Core\Utility\PathUtility\getRelativePath
‪static string null getRelativePath($sourcePath, $targetPath)
Definition: PathUtility.php:134
‪TYPO3\CMS\Core\Utility\PathUtility\dirnameDuringBootstrap
‪static string dirnameDuringBootstrap($path)
Definition: PathUtility.php:349
‪TYPO3\CMS\Core\Tests\Unit\Utility
‪TYPO3\CMS\Core\Core\Environment\getCurrentScript
‪static string getCurrentScript()
Definition: Environment.php:246
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\getCanonicalPathCorrectlyCleansPathDataProvider
‪string[][] getCanonicalPathCorrectlyCleansPathDataProvider()
Definition: PathUtilityTest.php:275
‪TYPO3\CMS\Core\Utility\PathUtility\getCanonicalPath
‪static string getCanonicalPath($path)
Definition: PathUtility.php:380
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\isAbsolutePathRespectsAllOperatingSystemsPathDataProvider
‪array[] isAbsolutePathRespectsAllOperatingSystemsPathDataProvider()
Definition: PathUtilityTest.php:486
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\isAbsolutePathRespectsAllOperatingSystems
‪isAbsolutePathRespectsAllOperatingSystems(string $inputPath, bool $isWindows, bool $expectedResult)
Definition: PathUtilityTest.php:544
‪TYPO3\CMS\Core\Core\Environment\getContext
‪static ApplicationContext getContext()
Definition: Environment.php:141
‪TYPO3\CMS\Core\Core\Environment\getProjectPath
‪static string getProjectPath()
Definition: Environment.php:177
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\basenameDuringBootstrapCorrectlyFetchesBasename
‪basenameDuringBootstrapCorrectlyFetchesBasename(string $inputPath, string $expectedResult)
Definition: PathUtilityTest.php:473
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\allowedAdditionalPathsAreEvaluatedDataProvider
‪static allowedAdditionalPathsAreEvaluatedDataProvider()
Definition: PathUtilityTest.php:591
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\dirnameDuringBootstrapCorrectlyFetchesParentDataProvider
‪string[][] dirnameDuringBootstrapCorrectlyFetchesParentDataProvider()
Definition: PathUtilityTest.php:404
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\getAbsolutePathOfRelativeReferencedFileOrPathResolvesFileCorrectlyDataProvider
‪array getAbsolutePathOfRelativeReferencedFileOrPathResolvesFileCorrectlyDataProvider()
Definition: PathUtilityTest.php:224
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\getAbsolutePathOfRelativeReferencedFileOrPathResolvesFileCorrectly
‪getAbsolutePathOfRelativeReferencedFileOrPathResolvesFileCorrectly(string $baseFileName, string $includeFileName, string $expectedFileName)
Definition: PathUtilityTest.php:264
‪TYPO3\CMS\Core\Utility\PathUtility\getCommonPrefix
‪static string null getCommonPrefix(array $paths)
Definition: PathUtility.php:171
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\isRelativePathResolvedCorrectly
‪isRelativePathResolvedCorrectly($source, $target, $expected)
Definition: PathUtilityTest.php:149
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\isCommonPrefixResolvedCorrectlyDataProvider
‪array isCommonPrefixResolvedCorrectlyDataProvider()
Definition: PathUtilityTest.php:50
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\isRelativePathResolvedCorrectlyDataProvider
‪array isRelativePathResolvedCorrectlyDataProvider()
Definition: PathUtilityTest.php:158
‪TYPO3\CMS\Core\Core\Environment\initialize
‪static initialize(ApplicationContext $context, bool $cli, bool $composerMode, string $projectPath, string $publicPath, string $varPath, string $configPath, string $currentScript, string $os)
Definition: Environment.php:111
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\basenameDuringBootstrapCorrectlyFetchesBasenameDataProvider
‪array basenameDuringBootstrapCorrectlyFetchesBasenameDataProvider()
Definition: PathUtilityTest.php:445
‪TYPO3\CMS\Core\Utility\PathUtility\isAbsolutePath
‪static bool isAbsolutePath($path)
Definition: PathUtility.php:296
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\isTrailingSeparatorSanitizedCorrectlyDataProvider
‪array isTrailingSeparatorSanitizedCorrectlyDataProvider()
Definition: PathUtilityTest.php:210
‪TYPO3\CMS\Core\Utility\PathUtility\sanitizeTrailingSeparator
‪static string sanitizeTrailingSeparator($path, $separator='/')
Definition: PathUtility.php:209
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Utility\PathUtility\hasProtocolAndScheme
‪static bool hasProtocolAndScheme(string $path)
Definition: PathUtility.php:463
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:43
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\allowedAdditionalPathsAreEvaluated
‪allowedAdditionalPathsAreEvaluated($lockRootPath, string $path, bool $expectation)
Definition: PathUtilityTest.php:624
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\$backupEnvironment
‪bool $backupEnvironment
Definition: PathUtilityTest.php:33
‪TYPO3\CMS\Core\Core\Environment\getConfigPath
‪static string getConfigPath()
Definition: Environment.php:236
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\isCommonPrefixResolvedCorrectly
‪isCommonPrefixResolvedCorrectly(array $paths, $expected)
Definition: PathUtilityTest.php:41
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\hasProtocolAndScheme
‪hasProtocolAndScheme(string $url, bool $result)
Definition: PathUtilityTest.php:586
‪TYPO3\CMS\Core\Utility\PathUtility\getAbsolutePathOfRelativeReferencedFileOrPath
‪static string getAbsolutePathOfRelativeReferencedFileOrPath($baseFilenameOrPath, $includeFileName)
Definition: PathUtility.php:329
‪TYPO3\CMS\Core\Tests\Unit\Utility\PathUtilityTest\getCanonicalPathCorrectlyCleansPath
‪getCanonicalPathCorrectlyCleansPath(string $inputName, string $expectedResult)
Definition: PathUtilityTest.php:379
‪TYPO3\CMS\Core\Core\Environment\getVarPath
‪static string getVarPath()
Definition: Environment.php:218