67c0c16f60efda88436e0719bbaf39e361f0ca6b
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Locking / SimpleLockStrategyTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Locking;
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
17 use TYPO3\CMS\Core\Locking\SimpleLockStrategy;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20 /**
21 * Testcase for \TYPO3\CMS\Core\Locking\SimpleLockStrategy
22 */
23 class SimpleLockStrategyTest extends \TYPO3\Components\TestingFramework\Core\UnitTestCase
24 {
25 /**
26 * @test
27 */
28 public function constructorCreatesLockDirectoryIfNotExisting()
29 {
30 GeneralUtility::rmdir(PATH_site . SimpleLockStrategy::FILE_LOCK_FOLDER, true);
31 new SimpleLockStrategy('999999999');
32 $this->assertTrue(is_dir(PATH_site . SimpleLockStrategy::FILE_LOCK_FOLDER));
33 }
34
35 /**
36 * @test
37 */
38 public function constructorSetsResourceToPathWithIdIfUsingSimpleLocking()
39 {
40 $lock = $this->getAccessibleMock(SimpleLockStrategy::class, ['dummy'], ['999999999']);
41 $this->assertSame(PATH_site . SimpleLockStrategy::FILE_LOCK_FOLDER . 'simple_' . md5('999999999'), $lock->_get('filePath'));
42 }
43
44 /**
45 * @test
46 */
47 public function acquireFixesPermissionsOnLockFile()
48 {
49 if (TYPO3_OS === 'WIN') {
50 $this->markTestSkipped('Test not available on Windows.');
51 }
52 // Use a very high id to be unique
53 /** @var SimpleLockStrategy|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\Components\TestingFramework\Core\AccessibleObjectInterface $lock */
54 $lock = $this->getAccessibleMock(SimpleLockStrategy::class, ['dummy'], ['999999999']);
55
56 $pathOfLockFile = $lock->_get('filePath');
57
58 $GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'] = '0777';
59
60 // Acquire lock, get actual file permissions and clean up
61 $lock->acquire();
62 clearstatcache();
63 $resultFilePermissions = substr(decoct(fileperms($pathOfLockFile)), 2);
64 $lock->release();
65 $this->assertEquals($resultFilePermissions, '0777');
66 }
67
68 /**
69 * @test
70 */
71 public function releaseRemovesLockfileInTypo3TempLocks()
72 {
73 /** @var SimpleLockStrategy|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\Components\TestingFramework\Core\AccessibleObjectInterface $lock */
74 $lock = $this->getAccessibleMock(SimpleLockStrategy::class, ['dummy'], ['999999999']);
75
76 $pathOfLockFile = $lock->_get('filePath');
77
78 $lock->acquire();
79 $lock->release();
80
81 $this->assertFalse(is_file($pathOfLockFile));
82 }
83
84 /**
85 * Dataprovider for releaseDoesNotRemoveFilesNotWithinTypo3TempLocksDirectory
86 */
87 public function invalidFileReferences()
88 {
89 return [
90 'not within PATH_site' => [tempnam(sys_get_temp_dir(), 'foo')],
91 'directory traversal' => [PATH_site . 'typo3temp/../typo3temp/var/locks/foo'],
92 'directory traversal 2' => [PATH_site . 'typo3temp/var/locks/../../var/locks/foo'],
93 'within uploads' => [PATH_site . 'uploads/TYPO3-Lock-Test']
94 ];
95 }
96
97 /**
98 * @test
99 * @dataProvider invalidFileReferences
100 * @param string $file
101 * @throws \PHPUnit_Framework_SkippedTestError
102 */
103 public function releaseDoesNotRemoveFilesNotWithinTypo3TempLocksDirectory($file)
104 {
105 // Create test file
106 touch($file);
107 if (!is_file($file)) {
108 $this->markTestIncomplete('releaseDoesNotRemoveFilesNotWithinTypo3TempLocksDirectory() skipped: Test file could not be created');
109 }
110 // Create instance, set lock file to invalid path
111 /** @var SimpleLockStrategy|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\Components\TestingFramework\Core\AccessibleObjectInterface $lock */
112 $lock = $this->getAccessibleMock(SimpleLockStrategy::class, ['dummy'], ['999999999']);
113 $lock->_set('filePath', $file);
114 $lock->_set('isAcquired', true);
115
116 // Call release method
117 $lock->release();
118 // Check if file is still there and clean up
119 $fileExists = is_file($file);
120 if (is_file($file)) {
121 unlink($file);
122 }
123 $this->assertTrue($fileExists);
124 }
125 }