Backward incompatibilities:
* The short notation of the `block` tag changed.
+ * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }})
* added a 'as' string to the block tag short notation ({% block title "Title" %} must now be {% block title as "Title" %})
* added an exception when a child template has a non-empty body (as it is always ignored when rendering)
--- /dev/null
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Twig_Node_SandboxPrint adds a check for the __toString() method
+ * when the variable is an object and the sandbox is activated.
+ *
+ * When there is a simple Print statement, like {{ article }},
+ * and if the sandbox is enabled, we need to check that the __toString()
+ * method is allowed if 'article' is an object.
+ *
+ * @package twig
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ * @version SVN: $Id$
+ */
+class Twig_Node_SandboxPrint extends Twig_Node_Print
+{
+ public function compile($compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('if ($this->env->hasExtension(\'sandbox\') && is_object(')
+ ->subcompile($this->expr)
+ ->raw('))'."\n")
+ ->write('{'."\n")
+ ->indent()
+ ->write('$this->env->getExtension(\'sandbox\')->checkMethodAllowed(')
+ ->subcompile($this->expr)
+ ->raw(', \'__toString\');'."\n")
+ ->outdent()
+ ->write('}'."\n")
+ ;
+
+ parent::compile($compiler);
+ }
+}
$this->filters[$filter[0]] = true;
}
}
+
+ // look for simple print statement ({{ article }})
+ if ($node instanceof Twig_Node_Print && $node->getExpression() instanceof Twig_Node_Expression_Name) {
+ return new Twig_Node_SandboxPrint($node->getExpression(), $node->getLine(), $node->getTag());
+ }
}
return $node;
'1_basic2' => '{{ name|upper }}',
'1_basic3' => '{% if name %}foo{% endif %}',
'1_basic4' => '{{ obj.bar }}',
+ '1_basic5' => '{{ obj }}',
'1_basic' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}',
);
}
} catch (Twig_Sandbox_SecurityError $e) {
}
+ $twig = $this->getEnvironment(true, self::$templates);
+ try {
+ $twig->loadTemplate('1_basic5')->render(self::$params);
+ $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template');
+ } catch (Twig_Sandbox_SecurityError $e) {
+ }
+
$twig = $this->getEnvironment(true, self::$templates, array(), array(), array('Object' => 'foo'));
$this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods');
+ $twig = $this->getEnvironment(true, self::$templates, array(), array(), array('Object' => '__toString'));
+ $this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allow some methods');
+
$twig = $this->getEnvironment(true, self::$templates, array(), array('upper'));
$this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters');
{
public $bar = 'bar';
+ public function __toString()
+ {
+ return 'foo';
+ }
+
public function foo()
{
return 'foo';