9
9
*/
10
10
namespace Magento \Framework \Filter ;
11
11
12
+ use Magento \Framework \Model \AbstractExtensibleModel ;
13
+ use Magento \Framework \Model \AbstractModel ;
14
+
12
15
class Template implements \Zend_Filter_Interface
13
16
{
14
17
/**
@@ -53,6 +56,19 @@ class Template implements \Zend_Filter_Interface
53
56
*/
54
57
protected $ string ;
55
58
59
+ /**
60
+ * @var string[]
61
+ */
62
+ private $ restrictedMethods = [
63
+ 'addafterfiltercallback ' ,
64
+ 'getresourcecollection ' ,
65
+ 'load ' ,
66
+ 'save ' ,
67
+ 'getcollection ' ,
68
+ 'getresource ' ,
69
+ 'getconfig ' ,
70
+ ];
71
+
56
72
/**
57
73
* @param \Magento\Framework\Stdlib\StringUtils $string
58
74
* @param array $variables
@@ -298,6 +314,46 @@ protected function getParameters($value)
298
314
return $ params ;
299
315
}
300
316
317
+ /**
318
+ * Validate method call initiated in a template.
319
+ *
320
+ * Deny calls for methods that may disrupt template processing.
321
+ *
322
+ * @param object $object
323
+ * @param string $method
324
+ * @return void
325
+ * @throws \InvalidArgumentException
326
+ */
327
+ private function validateVariableMethodCall ($ object , string $ method )
328
+ {
329
+ if ($ object === $ this ) {
330
+ if (in_array (mb_strtolower ($ method ), $ this ->restrictedMethods )) {
331
+ throw new \InvalidArgumentException ("Method $ method cannot be called from template. " );
332
+ }
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Check allowed methods for data objects.
338
+ *
339
+ * Deny calls for methods that may disrupt template processing.
340
+ *
341
+ * @param object $object
342
+ * @param string $method
343
+ * @return bool
344
+ * @throws \InvalidArgumentException
345
+ */
346
+ private function isAllowedDataObjectMethod ($ object , string $ method )
347
+ {
348
+ if ($ object instanceof AbstractExtensibleModel || $ object instanceof AbstractModel) {
349
+ if (in_array (mb_strtolower ($ method ), $ this ->restrictedMethods )) {
350
+ throw new \InvalidArgumentException ("Method $ method cannot be called from template. " );
351
+ }
352
+ }
353
+
354
+ return true ;
355
+ }
356
+
301
357
/**
302
358
* Return variable value for var construction
303
359
*
@@ -322,7 +378,7 @@ protected function getVariable($value, $default = '{no_value_defined}')
322
378
isset ($ stackVars [$ i - 1 ]['variable ' ])
323
379
&& $ stackVars [$ i - 1 ]['variable ' ] instanceof \Magento \Framework \DataObject
324
380
) {
325
- // If object calling methods or getting properties
381
+ // If data object calling methods or getting properties
326
382
if ($ stackVars [$ i ]['type ' ] == 'property ' ) {
327
383
$ caller = 'get ' . $ this ->string ->upperCaseWords ($ stackVars [$ i ]['name ' ], '_ ' , '' );
328
384
$ stackVars [$ i ]['variable ' ] = method_exists (
@@ -332,19 +388,33 @@ protected function getVariable($value, $default = '{no_value_defined}')
332
388
$ stackVars [$ i ]['name ' ]
333
389
);
334
390
} elseif ($ stackVars [$ i ]['type ' ] == 'method ' ) {
335
- // Calling of object method
336
- if (
337
- method_exists ($ stackVars [$ i - 1 ]['variable ' ], $ stackVars [$ i ]['name ' ])
338
- || substr ($ stackVars [$ i ]['name ' ], 0 , 3 ) == 'get '
391
+ // Calling of data object method
392
+ if (method_exists ($ stackVars [$ i - 1 ]['variable ' ], $ stackVars [$ i ]['name ' ])
393
+ || substr ($ stackVars [$ i ]['name ' ], 0 , 3 ) == 'get '
339
394
) {
340
395
$ stackVars [$ i ]['args ' ] = $ this ->getStackArgs ($ stackVars [$ i ]['args ' ]);
341
- $ stackVars [$ i ]['variable ' ] = call_user_func_array (
342
- [$ stackVars [$ i - 1 ]['variable ' ], $ stackVars [$ i ]['name ' ]],
343
- $ stackVars [$ i ]['args ' ]
344
- );
396
+ if ($ this ->isAllowedDataObjectMethod ($ stackVars [$ i - 1 ]['variable ' ], $ stackVars [$ i ]['name ' ])) {
397
+ $ stackVars [$ i ]['variable ' ] = call_user_func_array (
398
+ [$ stackVars [$ i - 1 ]['variable ' ], $ stackVars [$ i ]['name ' ]],
399
+ $ stackVars [$ i ]['args ' ]
400
+ );
401
+ }
345
402
}
346
403
}
347
404
$ last = $ i ;
405
+ } elseif (isset ($ stackVars [$ i - 1 ]['variable ' ])
406
+ && is_object ($ stackVars [$ i - 1 ]['variable ' ])
407
+ && $ stackVars [$ i ]['type ' ] == 'method '
408
+ ) {
409
+ // Calling object methods
410
+ $ object = $ stackVars [$ i - 1 ]['variable ' ];
411
+ $ method = $ stackVars [$ i ]['name ' ];
412
+ if (method_exists ($ object , $ method )) {
413
+ $ args = $ this ->getStackArgs ($ stackVars [$ i ]['args ' ]);
414
+ $ this ->validateVariableMethodCall ($ object , $ method );
415
+ $ stackVars [$ i ]['variable ' ] = call_user_func_array ([$ object , $ method ], $ args );
416
+ }
417
+ $ last = $ i ;
348
418
}
349
419
}
350
420
0 commit comments