fixed possible security problems with NUL bytes
authorFabien Potencier <fabien.potencier@gmail.com>
Fri, 17 Jun 2011 07:17:45 +0000 (09:17 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Fri, 17 Jun 2011 07:17:45 +0000 (09:17 +0200)
lib/Twig/Autoloader.php
lib/Twig/Compiler.php
lib/Twig/Loader/Filesystem.php
test/Twig/Tests/Loader/FilesystemTest.php

index 3315e23..ba43e14 100644 (file)
@@ -39,7 +39,7 @@ class Twig_Autoloader
             return;
         }
 
-        if (file_exists($file = dirname(__FILE__).'/../'.str_replace('_', '/', $class).'.php')) {
+        if (file_exists($file = dirname(__FILE__).'/../'.str_replace(array('_', "\0"), array('/', ''), $class).'.php')) {
             require $file;
         }
     }
index cae9f14..db2e8de 100644 (file)
@@ -129,7 +129,7 @@ class Twig_Compiler implements Twig_CompilerInterface
      */
     public function string($value)
     {
-        $this->source .= sprintf('"%s"', addcslashes($value, "\t\"\$\\"));
+        $this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\"));
 
         return $this;
     }
index 08e9c2c..be348aa 100644 (file)
@@ -131,6 +131,10 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface
 
     protected function validateName($name)
     {
+        if (false !== strpos($name, "\0")) {
+            throw new Twig_Error_Loader('A template name cannot contain NUL bytes.');
+        }
+
         $parts = explode('/', $name);
         $level = 0;
         foreach ($parts as $part) {
index 30d0c4d..c0437e8 100644 (file)
@@ -13,17 +13,23 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
 {
     /**
      * @dataProvider getSecurityTests
-     * @expectedException Twig_Error_Loader
      */
     public function testSecurity($template)
     {
         $loader = new Twig_Loader_Filesystem(array(__DIR__.'/../Fixtures'));
-        $loader->getCacheKey($template);
+
+        try {
+            $loader->getCacheKey($template);
+            $this->fail();
+        } catch (Twig_Error_Loader $e) {
+            $this->assertNotContains('Unable to find template', $e->getMessage());
+        }
     }
 
     public function getSecurityTests()
     {
         return array(
+            array("AutoloaderTest\0.php"),
             array('..\\AutoloaderTest.php'),
             array('..\\\\\\AutoloaderTest.php'),
             array('../AutoloaderTest.php'),