Skip to content

Commit ffc69d4

Browse files
authored
Merge pull request #3720 from magento-tsg/2.2.8-develop-pr74
[TSG] Backporting for 2.2 (pr74) (2.2.8-develop)
2 parents a06ac6d + ece9d90 commit ffc69d4

File tree

3 files changed

+97
-6
lines changed

3 files changed

+97
-6
lines changed

app/bootstrap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Environment initialization
99
*/
1010
error_reporting(E_ALL);
11+
stream_wrapper_unregister('phar');
1112
#ini_set('display_errors', 1);
1213

1314
/* PHP version validation */

lib/internal/Magento/Framework/Filter/Template.php

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
*/
1010
namespace Magento\Framework\Filter;
1111

12+
use Magento\Framework\Model\AbstractExtensibleModel;
13+
use Magento\Framework\Model\AbstractModel;
14+
1215
/**
1316
* @api
1417
*/
@@ -55,7 +58,14 @@ class Template implements \Zend_Filter_Interface
5558
/**
5659
* @var string[]
5760
*/
58-
private $restrictedMethods = ['addafterfiltercallback'];
61+
private $restrictedMethods = [
62+
'addafterfiltercallback',
63+
'getresourcecollection',
64+
'load',
65+
'save',
66+
'getcollection',
67+
'getresource'
68+
];
5969

6070
/**
6171
* @param \Magento\Framework\Stdlib\StringUtils $string
@@ -321,6 +331,27 @@ private function validateVariableMethodCall($object, string $method)
321331
}
322332
}
323333

334+
/**
335+
* Check allowed methods for data objects.
336+
*
337+
* Deny calls for methods that may disrupt template processing.
338+
*
339+
* @param object $object
340+
* @param string $method
341+
* @return bool
342+
* @throws \InvalidArgumentException
343+
*/
344+
private function isAllowedDataObjectMethod($object, string $method): bool
345+
{
346+
if ($object instanceof AbstractExtensibleModel || $object instanceof AbstractModel) {
347+
if (in_array(mb_strtolower($method), $this->restrictedMethods)) {
348+
throw new \InvalidArgumentException("Method $method cannot be called from template.");
349+
}
350+
}
351+
352+
return true;
353+
}
354+
324355
/**
325356
* Return variable value for var construction
326357
*
@@ -360,14 +391,20 @@ protected function getVariable($value, $default = '{no_value_defined}')
360391
|| substr($stackVars[$i]['name'], 0, 3) == 'get'
361392
) {
362393
$stackVars[$i]['args'] = $this->getStackArgs($stackVars[$i]['args']);
363-
$stackVars[$i]['variable'] = call_user_func_array(
364-
[$stackVars[$i - 1]['variable'], $stackVars[$i]['name']],
365-
$stackVars[$i]['args']
366-
);
394+
395+
if ($this->isAllowedDataObjectMethod($stackVars[$i - 1]['variable'], $stackVars[$i]['name'])) {
396+
$stackVars[$i]['variable'] = call_user_func_array(
397+
[$stackVars[$i - 1]['variable'], $stackVars[$i]['name']],
398+
$stackVars[$i]['args']
399+
);
400+
}
367401
}
368402
}
369403
$last = $i;
370-
} elseif (isset($stackVars[$i - 1]['variable']) && $stackVars[$i]['type'] == 'method') {
404+
} elseif (isset($stackVars[$i - 1]['variable'])
405+
&& is_object($stackVars[$i - 1]['variable'])
406+
&& $stackVars[$i]['type'] == 'method'
407+
) {
371408
// Calling object methods
372409
$object = $stackVars[$i - 1]['variable'];
373410
$method = $stackVars[$i]['name'];

lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,25 @@
66

77
namespace Magento\Framework\Filter\Test\Unit;
88

9+
use Magento\Store\Model\Store;
10+
911
class TemplateTest extends \PHPUnit\Framework\TestCase
1012
{
1113
/**
1214
* @var \Magento\Framework\Filter\Template
1315
*/
1416
private $templateFilter;
1517

18+
/**
19+
* @var Store
20+
*/
21+
private $store;
22+
1623
protected function setUp()
1724
{
1825
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
1926
$this->templateFilter = $objectManager->getObject(\Magento\Framework\Filter\Template::class);
27+
$this->store = $objectManager->getObject(Store::class);
2028
}
2129

2230
public function testFilter()
@@ -216,4 +224,49 @@ public function testInappropriateCallbacks()
216224
$this->templateFilter->setVariables(['filter' => $this->templateFilter]);
217225
$this->templateFilter->filter('Test {{var filter.addAfterFilterCallback(\'mb_strtolower\')}}');
218226
}
227+
228+
/**
229+
* Test adding callbacks when already filtering.
230+
*
231+
* @param string $method
232+
* @dataProvider disallowedMethods
233+
* @expectedException \InvalidArgumentException
234+
*
235+
* @return void
236+
*/
237+
public function testDisallowedMethods(string $method)
238+
{
239+
$this->templateFilter->setVariables(['store' => $this->store]);
240+
$this->templateFilter->filter('{{var store.'.$method.'()}}');
241+
}
242+
243+
/**
244+
* Data for testDisallowedMethods method.
245+
*
246+
* @return array
247+
*/
248+
public function disallowedMethods(): array
249+
{
250+
return [
251+
['getResourceCollection'],
252+
['load'],
253+
['save'],
254+
['getCollection'],
255+
['getResource'],
256+
];
257+
}
258+
259+
/**
260+
* Check that if calling a method of an object fails expected result is returned.
261+
*
262+
* @return void
263+
*/
264+
public function testInvalidMethodCall()
265+
{
266+
$this->templateFilter->setVariables(['dateTime' => '\DateTime']);
267+
$this->assertEquals(
268+
'\DateTime',
269+
$this->templateFilter->filter('{{var dateTime.createFromFormat(\'d\',\'1548201468\')}}')
270+
);
271+
}
219272
}

0 commit comments

Comments
 (0)