Skip to content

Commit fabfb01

Browse files
author
Oleksandr Gorkun
committed
MC-5947: Email templates breaking rendering
1 parent 0122d0b commit fabfb01

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

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

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ class Template implements \Zend_Filter_Interface
6363
*/
6464
protected $string;
6565

66+
/**
67+
* @var string[]
68+
*/
69+
private $restrictedMethods = ['addafterfiltercallback'];
70+
6671
/**
6772
* @param \Magento\Framework\Stdlib\StringUtils $string
6873
* @param array $variables
@@ -367,6 +372,25 @@ protected function getParameters($value)
367372
return $params;
368373
}
369374

375+
/**
376+
* Validate method call initiated in a template.
377+
*
378+
* Deny calls for methods that may disrupt template processing.
379+
*
380+
* @param object $object
381+
* @param string $method
382+
* @return void
383+
* @throws \InvalidArgumentException
384+
*/
385+
private function validateVariableMethodCall($object, string $method): void
386+
{
387+
if ($object === $this) {
388+
if (in_array(mb_strtolower($method), $this->restrictedMethods)) {
389+
throw new \InvalidArgumentException("Method $method cannot be called from template.");
390+
}
391+
}
392+
}
393+
370394
/**
371395
* Return variable value for var construction
372396
*
@@ -414,12 +438,12 @@ protected function getVariable($value, $default = '{no_value_defined}')
414438
$last = $i;
415439
} elseif (isset($stackVars[$i - 1]['variable']) && $stackVars[$i]['type'] == 'method') {
416440
// Calling object methods
417-
if (method_exists($stackVars[$i - 1]['variable'], $stackVars[$i]['name'])) {
418-
$stackVars[$i]['args'] = $this->getStackArgs($stackVars[$i]['args']);
419-
$stackVars[$i]['variable'] = call_user_func_array(
420-
[$stackVars[$i - 1]['variable'], $stackVars[$i]['name']],
421-
$stackVars[$i]['args']
422-
);
441+
$object = $stackVars[$i - 1]['variable'];
442+
$method = $stackVars[$i]['name'];
443+
if (method_exists($object, $method)) {
444+
$args = $this->getStackArgs($stackVars[$i]['args']);
445+
$this->validateVariableMethodCall($object, $method);
446+
$stackVars[$i]['variable'] = call_user_func_array([$object, $method], $args);
423447
}
424448
$last = $i;
425449
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,4 +380,15 @@ private function getObjectData()
380380
$dataObject->setAllVisibleItems($visibleItems);
381381
return $dataObject;
382382
}
383+
384+
/**
385+
* Test adding callbacks when already filtering.
386+
*
387+
* @expectedException \InvalidArgumentException
388+
*/
389+
public function testInappropriateCallbacks()
390+
{
391+
$this->templateFilter->setVariables(['filter' => $this->templateFilter]);
392+
$this->templateFilter->filter('Test {{var filter.addAfterFilterCallback(\'mb_strtolower\')}}');
393+
}
383394
}

0 commit comments

Comments
 (0)