diff --git a/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php index 8e4ed0b..32a0d53 100644 --- a/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php +++ b/core/lib/Drupal/Core/Template/TwigSandboxPolicy.php @@ -28,25 +28,29 @@ public function checkPropertyAllowed($obj, $property) {} * {@inheritdoc} */ public function checkMethodAllowed($obj, $method) { - if ($obj instanceof EntityInterface) { - // Only allow idempotent methods to be called on Entity objects. - $whitelist = [ - 'id' => TRUE, - 'label' => TRUE, - 'bundle' => TRUE, - 'get' => TRUE, - ]; - if (isset($whitelist[$method])) { - return TRUE; - } - - // If the method name starts with a whitelisted prefix, allow it. - if (preg_match('/^(get|has|is)[A-Za-z]/', $method)) { - return TRUE; - } - - throw new \Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj))); + if ($obj instanceof Attribute) { + // Allow any operations on the Attribute object as it is intended to be + // changed from a Twig template, for example calling addClass(). + return TRUE; } + + // Only allow idempotent methods to be called on objects. + $whitelist = [ + 'id' => TRUE, + 'label' => TRUE, + 'bundle' => TRUE, + 'get' => TRUE, + ]; + if (isset($whitelist[$method])) { + return TRUE; + } + + // If the method name starts with a whitelisted prefix, allow it. + if (preg_match('/^(get|has|is)[A-Za-z]/', $method)) { + return TRUE; + } + + throw new \Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj))); } }