Skip to content

Commit 292e6d3

Browse files
Merge pull request #6438 from magento-borg/2.3.7-bugfixes-120920
[CIA] Bugfixes
2 parents 263f508 + 137296e commit 292e6d3

File tree

28 files changed

+706
-174
lines changed

28 files changed

+706
-174
lines changed

app/code/Magento/Catalog/Model/Product/Gallery/UpdateHandler.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ protected function processDeletedImages($product, array &$images)
3434
foreach ($images as &$image) {
3535
if (!empty($image['removed'])) {
3636
if (!empty($image['value_id'])) {
37-
if (preg_match('/\.\.(\\\|\/)/', $image['file'])) {
38-
continue;
39-
}
4037
$recordsToDelete[] = $image['value_id'];
4138
$catalogPath = $this->mediaConfig->getBaseMediaPath();
42-
$isFile = $this->mediaDirectory->isFile($catalogPath . $image['file']);
39+
$filePath = $this->mediaDirectory->getRelativePath($catalogPath . $image['file']);
40+
$isFile = $this->mediaDirectory->isFile($filePath);
4341
// only delete physical files if they are not used by any other products and if this file exist
4442
if ($isFile && !($this->resourceModel->countImageUses($image['file']) > 1)) {
4543
$filesToDelete[] = ltrim($image['file'], '/');
@@ -116,6 +114,7 @@ protected function extractStoreIds($product)
116114
*
117115
* @param array $files
118116
* @return null
117+
* @throws \Magento\Framework\Exception\FileSystemException
119118
* @since 101.0.0
120119
*/
121120
protected function removeDeletedImages(array $files)
@@ -125,5 +124,7 @@ protected function removeDeletedImages(array $files)
125124
foreach ($files as $filePath) {
126125
$this->mediaDirectory->delete($catalogPath . '/' . $filePath);
127126
}
127+
128+
return null;
128129
}
129130
}

app/code/Magento/Cms/Helper/Wysiwyg/Images.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
/**
1111
* Wysiwyg Images Helper.
12+
*
13+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1214
*/
1315
class Images extends \Magento\Framework\App\Helper\AbstractHelper
1416
{
@@ -64,6 +66,11 @@ class Images extends \Magento\Framework\App\Helper\AbstractHelper
6466
*/
6567
protected $escaper;
6668

69+
/**
70+
* @var \Magento\Framework\Filesystem\Directory\Read
71+
*/
72+
private $_readDirectory;
73+
6774
/**
6875
* Construct
6976
*
@@ -87,6 +94,7 @@ public function __construct(
8794

8895
$this->_directory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
8996
$this->_directory->create($this->getStorageRoot());
97+
$this->_readDirectory = $filesystem->getDirectoryReadByPath($this->getStorageRoot());
9098
}
9199

92100
/**
@@ -166,7 +174,9 @@ public function convertIdToPath($id)
166174
return $this->getStorageRoot();
167175
} else {
168176
$path = $this->getStorageRoot() . $this->idDecode($id);
169-
if (preg_match('/\.\.(\\\|\/)/', $path)) {
177+
try {
178+
$this->_readDirectory->getAbsolutePath($path);
179+
} catch (\Exception $e) {
170180
throw new \InvalidArgumentException('Path is invalid');
171181
}
172182

@@ -225,6 +235,7 @@ public function getImageHtmlDeclaration($filename, $renderAsTag = false)
225235

226236
/**
227237
* Return path of the current selected directory or root directory for startup
238+
*
228239
* Try to create target directory if it doesn't exist
229240
*
230241
* @return string
@@ -294,6 +305,7 @@ public function idEncode($string)
294305
public function idDecode($string)
295306
{
296307
$string = strtr($string, ':_-', '+/=');
308+
//phpcs:ignore Magento2.Functions.DiscouragedFunction
297309
return base64_decode($string);
298310
}
299311

@@ -315,7 +327,7 @@ public function getShortFilename($filename, $maxLength = 20)
315327
/**
316328
* Set user-traversable image directory subpath relative to media directory and relative to nested storage root
317329
*
318-
* @var string $subpath
330+
* @param string $subpath
319331
* @return void
320332
*/
321333
public function setImageDirectorySubpath($subpath)

app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,10 @@ public function uploadFile($targetPath, $type = null)
545545
{
546546
$targetPath = $this->file->getRealPathSafety($targetPath);
547547

548+
if ($this->file->isDirectory($targetPath)) {
549+
$targetPath = $targetPath . DIRECTORY_SEPARATOR;
550+
}
551+
548552
if (!$this->isPathAllowed($targetPath, $this->getConditionsForExcludeDirs()) || strlen($targetPath) > 255) {
549553
throw new \Magento\Framework\Exception\LocalizedException(
550554
__('We can\'t upload the file to current folder right now. Please try another folder.')

app/code/Magento/Cms/Test/Unit/Helper/Wysiwyg/ImagesTest.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace Magento\Cms\Test\Unit\Helper\Wysiwyg;
77

88
use Magento\Cms\Model\Wysiwyg\Config as WysiwygConfig;
9+
use Magento\Framework\Exception\ValidatorException;
910

1011
/**
1112
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -32,6 +33,11 @@ class ImagesTest extends \PHPUnit\Framework\TestCase
3233
*/
3334
protected $directoryWriteMock;
3435

36+
/**
37+
* @var \Magento\Framework\Filesystem\Directory\Read|\PHPUnit_Framework_MockObject_MockObject
38+
*/
39+
protected $directoryReadMock;
40+
3541
/**
3642
* @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
3743
*/
@@ -115,10 +121,18 @@ protected function setUp()
115121
]
116122
);
117123

124+
$this->directoryReadMock = $this->getMockBuilder(\Magento\Framework\Filesystem\Directory\Read::class)
125+
->setConstructorArgs(['path' => $this->path])
126+
->disableOriginalConstructor()
127+
->getMock();
128+
118129
$this->filesystemMock = $this->createMock(\Magento\Framework\Filesystem::class);
119130
$this->filesystemMock->expects($this->once())
120131
->method('getDirectoryWrite')
121132
->willReturn($this->directoryWriteMock);
133+
$this->filesystemMock->expects($this->once())
134+
->method('getDirectoryReadByPath')
135+
->willReturn($this->directoryReadMock);
122136

123137
$this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
124138
->setMethods(
@@ -240,12 +254,15 @@ public function testConvertIdToPathNodeRoot()
240254
$this->assertEquals($this->imagesHelper->getStorageRoot(), $this->imagesHelper->convertIdToPath($pathId));
241255
}
242256

243-
/**
244-
* @expectedException \InvalidArgumentException
245-
* @expectedExceptionMessage Path is invalid
246-
*/
247257
public function testConvertIdToPathInvalid()
248258
{
259+
$this->expectException('InvalidArgumentException');
260+
$this->expectExceptionMessage('Path is invalid');
261+
$this->directoryReadMock->expects($this->any())
262+
->method('getAbsolutePath')
263+
->will(
264+
$this->throwException(new ValidatorException(__("Error")))
265+
);
249266
$this->imagesHelper->convertIdToPath('Ly4uLy4uLy4uLy4uLy4uL3dvcms-');
250267
}
251268

app/code/Magento/ImportExport/Controller/Adminhtml/Export/File/Download.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99

1010
use Magento\Backend\App\Action;
1111
use Magento\Framework\App\Action\HttpGetActionInterface;
12+
use Magento\Framework\App\Filesystem\DirectoryList;
1213
use Magento\Framework\App\Response\Http\FileFactory;
1314
use Magento\Framework\Exception\LocalizedException;
14-
use Magento\Framework\App\Filesystem\DirectoryList;
15-
use Magento\ImportExport\Controller\Adminhtml\Export as ExportController;
1615
use Magento\Framework\Filesystem;
16+
use Magento\ImportExport\Controller\Adminhtml\Export as ExportController;
17+
use Throwable;
1718

1819
/**
1920
* Controller that download file by name.
@@ -60,7 +61,13 @@ public function __construct(
6061
public function execute()
6162
{
6263
$fileName = $this->getRequest()->getParam('filename');
63-
if (empty($fileName) || preg_match('/\.\.(\\\|\/)/', $fileName) !== 0) {
64+
$exportDirectory = $this->filesystem->getDirectoryRead(DirectoryList::VAR_EXPORT);
65+
try {
66+
$fileExist = $exportDirectory->isExist($fileName);
67+
} catch (Throwable $e) {
68+
$fileExist = false;
69+
}
70+
if (empty($fileName) || !$fileExist) {
6471
throw new LocalizedException(__('Please provide valid export file name'));
6572
}
6673
try {
@@ -72,8 +79,14 @@ public function execute()
7279
$directory->readFile($path),
7380
DirectoryList::VAR_DIR
7481
);
82+
} else {
83+
$fileExist = false;
7584
}
7685
} catch (LocalizedException | \Exception $exception) {
86+
$fileExist = false;
87+
}
88+
89+
if (!$fileExist) {
7790
throw new LocalizedException(__('There are no export file with such name %1', $fileName));
7891
}
7992
}

app/code/Magento/ImportExport/Helper/Report.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
namespace Magento\ImportExport\Helper;
88

99
use Magento\Framework\App\Filesystem\DirectoryList;
10+
use Magento\Framework\Exception\ValidatorException;
1011
use Magento\ImportExport\Model\Import;
12+
use Magento\Framework\Filesystem\Directory\ReadInterface;
1113

1214
/**
1315
* ImportExport history reports helper
@@ -27,6 +29,11 @@ class Report extends \Magento\Framework\App\Helper\AbstractHelper
2729
*/
2830
protected $varDirectory;
2931

32+
/**
33+
* @var ReadInterface
34+
*/
35+
private $importHistoryDirectory;
36+
3037
/**
3138
* Construct
3239
*
@@ -41,6 +48,8 @@ public function __construct(
4148
) {
4249
$this->timeZone = $timeZone;
4350
$this->varDirectory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
51+
$importHistoryPath = $this->varDirectory->getAbsolutePath('import_history');
52+
$this->importHistoryDirectory = $filesystem->getDirectoryReadByPath($importHistoryPath);
4453
parent::__construct($context);
4554
}
4655

@@ -127,11 +136,12 @@ public function getReportSize($filename)
127136
*/
128137
protected function getFilePath($filename)
129138
{
130-
if (preg_match('/\.\.(\\\|\/)/', $filename)) {
131-
throw new \InvalidArgumentException('Filename has not permitted symbols in it');
139+
try {
140+
$filePath = $this->varDirectory->getRelativePath($this->importHistoryDirectory->getAbsolutePath($filename));
141+
} catch (ValidatorException $e) {
142+
throw new \InvalidArgumentException('File not found');
132143
}
133-
134-
return $this->varDirectory->getRelativePath(Import::IMPORT_HISTORY_DIR . $filename);
144+
return $filePath;
135145
}
136146

137147
/**

app/code/Magento/ImportExport/Test/Unit/Controller/Adminhtml/Export/File/DownloadTest.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77

88
namespace Magento\ImportExport\Test\Unit\Controller\Adminhtml\Export\File;
99

10-
use Magento\Framework\Filesystem;
1110
use Magento\Backend\App\Action\Context;
11+
use Magento\Framework\App\Filesystem\DirectoryList;
1212
use Magento\Framework\App\Request\Http;
13+
use Magento\Framework\App\Response\Http\FileFactory;
1314
use Magento\Framework\App\ResponseInterface;
14-
use PHPUnit\Framework\MockObject\MockObject;
15+
use Magento\Framework\Filesystem;
1516
use Magento\Framework\Filesystem\Directory\Read;
16-
use Magento\Framework\App\Filesystem\DirectoryList;
17-
use Magento\Framework\App\Response\Http\FileFactory;
18-
use Magento\ImportExport\Controller\Adminhtml\Export\File\Download;
1917
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
18+
use Magento\ImportExport\Controller\Adminhtml\Export\File\Download;
19+
use PHPUnit\Framework\MockObject\MockObject;
2020

2121
/**
2222
* Unit tests for \Magento\ImportExport\Controller\Adminhtml\Export\File\Download.
@@ -56,7 +56,7 @@ class DownloadTest extends \PHPUnit\Framework\TestCase
5656
/**
5757
* @var Read|MockObject
5858
*/
59-
private $readMock;
59+
private $directoryMock;
6060

6161
/**
6262
* @inheritdoc
@@ -70,9 +70,11 @@ protected function setUp()
7070
['getRequest', 'getObjectManager', 'getResultRedirectFactory']
7171
);
7272
$this->fileFactoryMock = $this->createPartialMock(FileFactory::class, ['create']);
73-
$this->fileSystemMock = $this->createPartialMock(Filesystem::class, ['getDirectoryRead']);
73+
$this->fileSystemMock = $this->getMockBuilder(Filesystem::class)
74+
->disableOriginalConstructor()
75+
->getMock();
7476
$this->requestMock = $this->createPartialMock(Http::class, ['getParam']);
75-
$this->readMock = $this->createPartialMock(Read::class, ['isFile', 'readFile']);
77+
$this->directoryMock = $this->createPartialMock(Read::class, ['isFile', 'readFile','isExist']);
7678

7779
$this->contextMock->expects($this->once())->method('getRequest')->willReturn($this->requestMock);
7880

@@ -98,7 +100,7 @@ public function testExecute(): void
98100
$fileContent = 'content';
99101

100102
$this->processDownloadAction($fileName, $path);
101-
$this->readMock->expects($this->once())->method('readFile')->with($path)->willReturn($fileContent);
103+
$this->directoryMock->expects($this->once())->method('readFile')->with($path)->willReturn($fileContent);
102104
$response = $this->createMock(ResponseInterface::class);
103105
$this->fileFactoryMock->expects($this->once())
104106
->method('create')
@@ -135,7 +137,7 @@ public function testExecuteWithNonExistanceFile(): void
135137
$path = 'export/' . $fileName;
136138

137139
$this->processDownloadAction($fileName, $path);
138-
$this->readMock->expects($this->once())
140+
$this->directoryMock->expects($this->once())
139141
->method('readFile')
140142
->with($path)
141143
->willThrowException(new \Exception('Message'));
@@ -153,10 +155,10 @@ public function testExecuteWithNonExistanceFile(): void
153155
private function processDownloadAction(string $fileName, string $path): void
154156
{
155157
$this->requestMock->expects($this->once())->method('getParam')->with('filename')->willReturn($fileName);
156-
$this->fileSystemMock->expects($this->once())
158+
$this->fileSystemMock->expects($this->any())
157159
->method('getDirectoryRead')
158-
->with(DirectoryList::VAR_DIR)
159-
->willReturn($this->readMock);
160-
$this->readMock->expects($this->once())->method('isFile')->with($path)->willReturn(true);
160+
->willReturn($this->directoryMock);
161+
$this->directoryMock->expects($this->once())->method('isExist')->willReturn(true);
162+
$this->directoryMock->expects($this->once())->method('isFile')->with($path)->willReturn(true);
161163
}
162164
}

0 commit comments

Comments
 (0)