Skip to content

Commit 32fa6a1

Browse files
merge magento/2.4.0-develop into magento-tsg/2.4.0-develop-pr45
2 parents 60cf1b6 + 5139f7d commit 32fa6a1

File tree

5 files changed

+158
-7
lines changed

5 files changed

+158
-7
lines changed

app/code/Magento/Theme/Helper/Storage.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use Magento\Framework\App\Filesystem\DirectoryList;
1313
use Magento\Framework\App\ObjectManager;
14+
use Magento\Framework\Filesystem\DriverInterface;
1415

1516
/**
1617
* Handles the storage of media files like images and fonts.
@@ -97,6 +98,10 @@ class Storage extends \Magento\Framework\App\Helper\AbstractHelper
9798
* @var \Magento\Framework\Filesystem\Io\File
9899
*/
99100
private $file;
101+
/**
102+
* @var DriverInterface
103+
*/
104+
private $filesystemDriver;
100105

101106
/**
102107
* @param \Magento\Framework\App\Helper\Context $context
@@ -105,6 +110,7 @@ class Storage extends \Magento\Framework\App\Helper\AbstractHelper
105110
* @param \Magento\Framework\View\Design\Theme\FlyweightFactory $themeFactory
106111
* @param \Magento\Framework\Filesystem\Io\File|null $file
107112
*
113+
* @param DriverInterface|null $filesystemDriver
108114
* @throws \Magento\Framework\Exception\FileSystemException
109115
* @throws \Magento\Framework\Exception\ValidatorException
110116
*/
@@ -113,7 +119,8 @@ public function __construct(
113119
\Magento\Framework\Filesystem $filesystem,
114120
\Magento\Backend\Model\Session $session,
115121
\Magento\Framework\View\Design\Theme\FlyweightFactory $themeFactory,
116-
\Magento\Framework\Filesystem\Io\File $file = null
122+
\Magento\Framework\Filesystem\Io\File $file = null,
123+
DriverInterface $filesystemDriver = null
117124
) {
118125
parent::__construct($context);
119126
$this->filesystem = $filesystem;
@@ -124,6 +131,7 @@ public function __construct(
124131
$this->file = $file ?: ObjectManager::getInstance()->get(
125132
\Magento\Framework\Filesystem\Io\File::class
126133
);
134+
$this->filesystemDriver = $filesystemDriver ?: ObjectManager::getInstance()->get(DriverInterface::class);
127135
}
128136

129137
/**
@@ -247,7 +255,16 @@ public function getCurrentPath()
247255
if ($path && $path !== self::NODE_ROOT) {
248256
$path = $this->convertIdToPath($path);
249257

250-
if ($this->mediaDirectoryWrite->isDirectory($path) && 0 === strpos($path, (string) $currentPath)) {
258+
$path = $this->filesystemDriver->getRealPathSafety($path);
259+
260+
if (strpos($path, $currentPath) !== 0) {
261+
$path = $currentPath;
262+
}
263+
264+
if ($this->mediaDirectoryWrite->isDirectory($path)
265+
&& strpos($path, $currentPath) === 0
266+
&& $path !== $currentPath
267+
) {
251268
$currentPath = $this->mediaDirectoryWrite->getRelativePath($path);
252269
}
253270
}

app/code/Magento/Theme/Model/Wysiwyg/Storage.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use Magento\Framework\App\Filesystem\DirectoryList;
1010
use Magento\Framework\App\ObjectManager;
11+
use Magento\Framework\Filesystem\DriverInterface;
1112

1213
/**
1314
* Theme wysiwyg storage model
@@ -18,11 +19,15 @@ class Storage
1819
{
1920
/**
2021
* Type font
22+
*
23+
* Represents the font type
2124
*/
2225
const TYPE_FONT = 'font';
2326

2427
/**
2528
* Type image
29+
*
30+
* Represents the image type
2631
*/
2732
const TYPE_IMAGE = 'image';
2833

@@ -82,6 +87,11 @@ class Storage
8287
*/
8388
private $file;
8489

90+
/**
91+
* @var DriverInterface
92+
*/
93+
private $filesystemDriver;
94+
8595
/**
8696
* Initialize dependencies
8797
*
@@ -92,6 +102,7 @@ class Storage
92102
* @param \Magento\Framework\Url\EncoderInterface $urlEncoder
93103
* @param \Magento\Framework\Url\DecoderInterface $urlDecoder
94104
* @param \Magento\Framework\Filesystem\Io\File|null $file
105+
* @param DriverInterface|null $filesystemDriver
95106
*
96107
* @throws \Magento\Framework\Exception\FileSystemException
97108
*/
@@ -102,7 +113,8 @@ public function __construct(
102113
\Magento\Framework\Image\AdapterFactory $imageFactory,
103114
\Magento\Framework\Url\EncoderInterface $urlEncoder,
104115
\Magento\Framework\Url\DecoderInterface $urlDecoder,
105-
\Magento\Framework\Filesystem\Io\File $file = null
116+
\Magento\Framework\Filesystem\Io\File $file = null,
117+
DriverInterface $filesystemDriver = null
106118
) {
107119
$this->mediaWriteDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
108120
$this->_helper = $helper;
@@ -113,6 +125,8 @@ public function __construct(
113125
$this->file = $file ?: ObjectManager::getInstance()->get(
114126
\Magento\Framework\Filesystem\Io\File::class
115127
);
128+
$this->filesystemDriver = $filesystemDriver ?: ObjectManager::getInstance()
129+
->get(DriverInterface::class);
116130
}
117131

118132
/**
@@ -327,8 +341,12 @@ public function deleteDirectory($path)
327341
{
328342
$rootCmp = rtrim($this->_helper->getStorageRoot(), '/');
329343
$pathCmp = rtrim($path, '/');
344+
$absolutePath = rtrim(
345+
$this->filesystemDriver->getRealPathSafety($this->mediaWriteDirectory->getAbsolutePath($path)),
346+
'/'
347+
);
330348

331-
if ($rootCmp == $pathCmp) {
349+
if ($rootCmp == $pathCmp || $rootCmp === $absolutePath) {
332350
throw new \Magento\Framework\Exception\LocalizedException(
333351
__('We can\'t delete root directory %1 right now.', $path)
334352
);

app/code/Magento/Theme/Test/Unit/Helper/StorageTest.php

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
use Magento\Framework\Url\EncoderInterface;
2020
use Magento\Framework\View\Design\Theme\Customization;
2121
use Magento\Framework\View\Design\Theme\FlyweightFactory;
22+
use Magento\Framework\Filesystem\DriverInterface;
2223
use Magento\Theme\Helper\Storage;
23-
use Magento\Theme\Model\Theme;
2424
use PHPUnit\Framework\MockObject\MockObject;
25+
use Magento\Theme\Model\Theme;
2526
use PHPUnit\Framework\TestCase;
2627

2728
/**
@@ -91,6 +92,11 @@ class StorageTest extends TestCase
9192

9293
protected $requestParams;
9394

95+
/**
96+
* @var DriverInterface|MockObject
97+
*/
98+
private $filesystemDriver;
99+
94100
protected function setUp(): void
95101
{
96102
$this->customizationPath = '/' . implode('/', ['var', 'theme']);
@@ -117,6 +123,7 @@ protected function setUp(): void
117123
$this->contextHelper->expects($this->any())->method('getUrlEncoder')->willReturn($this->urlEncoder);
118124
$this->contextHelper->expects($this->any())->method('getUrlDecoder')->willReturn($this->urlDecoder);
119125
$this->themeFactory->expects($this->any())->method('create')->willReturn($this->theme);
126+
$this->filesystemDriver = $this->createMock(DriverInterface::class);
120127

121128
$this->theme->expects($this->any())
122129
->method('getCustomization')
@@ -135,7 +142,9 @@ protected function setUp(): void
135142
$this->contextHelper,
136143
$this->filesystem,
137144
$this->session,
138-
$this->themeFactory
145+
$this->themeFactory,
146+
null,
147+
$this->filesystemDriver
139148
);
140149
}
141150

@@ -279,6 +288,9 @@ public function testGetThumbnailPathNotFound()
279288
{
280289
$this->expectException('InvalidArgumentException');
281290
$this->expectExceptionMessage('The image not found');
291+
292+
$this->filesystemDriver->method('getRealpathSafety')
293+
->willReturnArgument(0);
282294
$image = 'notFoundImage.png';
283295
$root = '/image';
284296
$sourceNode = '/not/a/root';
@@ -456,4 +468,67 @@ public function testGetThemeNotFound()
456468
);
457469
$helper->getStorageRoot();
458470
}
471+
472+
/**
473+
* @dataProvider getCurrentPathDataProvider
474+
*/
475+
public function testGetCurrentPathCachesResult()
476+
{
477+
$this->request->expects($this->once())
478+
->method('getParam')
479+
->with(Storage::PARAM_NODE)
480+
->willReturn(Storage::NODE_ROOT);
481+
482+
$actualPath = $this->helper->getCurrentPath();
483+
self::assertSame('/image', $actualPath);
484+
}
485+
486+
/**
487+
* @dataProvider getCurrentPathDataProvider
488+
*/
489+
public function testGetCurrentPath(
490+
string $expectedPath,
491+
string $requestedPath,
492+
?bool $isDirectory = null,
493+
?string $relativePath = null,
494+
?string $resolvedPath = null
495+
) {
496+
$this->directoryWrite->method('isDirectory')
497+
->willReturn($isDirectory);
498+
499+
$this->directoryWrite->method('getRelativePath')
500+
->willReturn($relativePath);
501+
502+
$this->urlDecoder->method('decode')
503+
->willReturnArgument(0);
504+
505+
if ($resolvedPath) {
506+
$this->filesystemDriver->method('getRealpathSafety')
507+
->willReturn($resolvedPath);
508+
} else {
509+
$this->filesystemDriver->method('getRealpathSafety')
510+
->willReturnArgument(0);
511+
}
512+
513+
$this->request->method('getParam')
514+
->with(Storage::PARAM_NODE)
515+
->willReturn($requestedPath);
516+
517+
$actualPath = $this->helper->getCurrentPath();
518+
519+
self::assertSame($expectedPath, $actualPath);
520+
}
521+
522+
public function getCurrentPathDataProvider(): array
523+
{
524+
$rootPath = '/' . \Magento\Theme\Model\Wysiwyg\Storage::TYPE_IMAGE;
525+
526+
return [
527+
'requested path "root" should short-circuit' => [$rootPath, Storage::NODE_ROOT],
528+
'non-existent directory should default to the base path' => [$rootPath, $rootPath . '/foo'],
529+
'requested path that resolves to a bad path should default to root' =>
530+
[$rootPath, $rootPath . '/something', true, null, '/bar'],
531+
'real path should resolve to relative path' => ['foo/', $rootPath . '/foo', true, 'foo/'],
532+
];
533+
}
459534
}

app/code/Magento/Theme/Test/Unit/Model/Wysiwyg/StorageTest.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Magento\Theme\Helper\Storage;
2424
use PHPUnit\Framework\MockObject\MockObject;
2525
use PHPUnit\Framework\TestCase;
26+
use Magento\Framework\Filesystem\DriverInterface;
2627

2728
/**
2829
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -74,6 +75,11 @@ class StorageTest extends TestCase
7475
*/
7576
protected $urlDecoder;
7677

78+
/**
79+
* @var DriverInterface|MockObject
80+
*/
81+
private $filesystemDriver;
82+
7783
protected function setUp(): void
7884
{
7985
$this->_filesystem = $this->createMock(Filesystem::class);
@@ -114,6 +120,7 @@ function ($path) {
114120
$this->directoryWrite = $this->createMock(Write::class);
115121
$this->urlEncoder = $this->createPartialMock(EncoderInterface::class, ['encode']);
116122
$this->urlDecoder = $this->createPartialMock(DecoderInterface::class, ['decode']);
123+
$this->filesystemDriver = $this->createMock(DriverInterface::class);
117124

118125
$this->_filesystem->expects(
119126
$this->once()
@@ -129,7 +136,9 @@ function ($path) {
129136
$this->_objectManager,
130137
$this->_imageFactory,
131138
$this->urlEncoder,
132-
$this->urlDecoder
139+
$this->urlDecoder,
140+
null,
141+
$this->filesystemDriver
133142
);
134143

135144
$this->_storageRoot = '/root';
@@ -577,6 +586,33 @@ public function testDeleteRootDirectory()
577586
$this->_storageModel->deleteDirectory($directoryPath);
578587
}
579588

589+
/**
590+
* cover \Magento\Theme\Model\Wysiwyg\Storage::deleteDirectory
591+
*/
592+
public function testDeleteRootDirectoryRelative()
593+
{
594+
$this->expectException(
595+
\Magento\Framework\Exception\LocalizedException::class
596+
);
597+
598+
$directoryPath = $this->_storageRoot;
599+
$fakePath = 'fake/relative/path';
600+
601+
$this->directoryWrite->method('getAbsolutePath')
602+
->with($fakePath)
603+
->willReturn($directoryPath);
604+
605+
$this->filesystemDriver->method('getRealPathSafety')
606+
->with($directoryPath)
607+
->willReturn($directoryPath);
608+
609+
$this->_helperStorage
610+
->method('getStorageRoot')
611+
->willReturn($directoryPath);
612+
613+
$this->_storageModel->deleteDirectory($fakePath);
614+
}
615+
580616
/**
581617
* @return array
582618
*/

app/code/Magento/Theme/etc/di.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,4 +309,9 @@
309309
<argument name="cache" xsi:type="object">configured_design_cache</argument>
310310
</arguments>
311311
</type>
312+
<type name="Magento\Theme\Helper\Storage">
313+
<arguments>
314+
<argument name="filesystemDriver" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
315+
</arguments>
316+
</type>
312317
</config>

0 commit comments

Comments
 (0)