From 83a0cbab91511af73ffe5233b190404c38345df1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 24 Jun 2011 11:04:41 +0200 Subject: [PATCH] fixed method case-sensitivity when using the sandbox mode --- CHANGELOG | 1 + lib/Twig/Sandbox/SecurityPolicy.php | 10 +++++++--- test/Twig/Tests/Extension/SandboxTest.php | 18 ++++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7543250..5eb5b69 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Changes: + * fixed method case-sensitivity when using the sandbox mode * added timezone support for the date filter * fixed possible security problems with NUL bytes diff --git a/lib/Twig/Sandbox/SecurityPolicy.php b/lib/Twig/Sandbox/SecurityPolicy.php index 0fd2c0b..ba912ef 100644 --- a/lib/Twig/Sandbox/SecurityPolicy.php +++ b/lib/Twig/Sandbox/SecurityPolicy.php @@ -27,7 +27,7 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac { $this->allowedTags = $allowedTags; $this->allowedFilters = $allowedFilters; - $this->allowedMethods = $allowedMethods; + $this->setAllowedMethods($allowedMethods); $this->allowedProperties = $allowedProperties; $this->allowedFunctions = $allowedFunctions; } @@ -44,7 +44,10 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac public function setAllowedMethods(array $methods) { - $this->allowedMethods = $methods; + $this->allowedMethods = array(); + foreach ($methods as $class => $m) { + $this->allowedMethods[$class] = array_map('strtolower', is_array($m) ? $m : array($m)); + } } public function setAllowedProperties(array $properties) @@ -85,9 +88,10 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac } $allowed = false; + $method = strtolower($method); foreach ($this->allowedMethods as $class => $methods) { if ($obj instanceof $class) { - $allowed = in_array($method, is_array($methods) ? $methods : array($methods)); + $allowed = in_array($method, $methods); break; } diff --git a/test/Twig/Tests/Extension/SandboxTest.php b/test/Twig/Tests/Extension/SandboxTest.php index a0c07ad..ce9a1ed 100644 --- a/test/Twig/Tests/Extension/SandboxTest.php +++ b/test/Twig/Tests/Extension/SandboxTest.php @@ -29,6 +29,7 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase '1_basic5' => '{{ obj }}', '1_basic6' => '{{ arr.obj }}', '1_basic7' => '{{ cycle(["foo","bar"], 1) }}', + '1_basic8' => '{{ obj.getfoobar }}{{ obj.getFooBar }}', '1_basic' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', ); } @@ -109,6 +110,12 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array(), array('cycle')); $this->assertEquals('bar', $twig->loadTemplate('1_basic7')->render(self::$params), 'Sandbox allow some functions'); + foreach (array('getfoobar', 'getFoobar', 'getFooBar') as $name) { + $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('Object' => $name)); + Object::reset(); + $this->assertEquals('foobarfoobar', $twig->loadTemplate('1_basic8')->render(self::$params), 'Sandbox allow methods in a case-insensitive way'); + $this->assertEquals(2, Object::$called['getFooBar'], 'Sandbox only calls method once'); + } } public function testSandboxLocallySetForAnInclude() @@ -158,13 +165,13 @@ EOF class Object { - static public $called = array('__toString' => 0, 'foo' => 0); + static public $called = array('__toString' => 0, 'foo' => 0, 'getFooBar' => 0); public $bar = 'bar'; static public function reset() { - self::$called = array('__toString' => 0, 'foo' => 0); + self::$called = array('__toString' => 0, 'foo' => 0, 'getFooBar' => 0); } public function __toString() @@ -180,4 +187,11 @@ class Object return 'foo'; } + + public function getFooBar() + { + ++self::$called['getFooBar']; + + return 'foobar'; + } } -- 1.7.2.5