Repository: twigphp/Twig (php)

Issue:
File check and PHP open_basedir warning
In this line https://github.com/twigphp/Twig/blob/ac0f512553fab5a685aa0ed1e357d20a644b81bf/src/Loader/FilesystemLoader.php#L212 PHP throws a warning about accessing file outside `open_basedir` on Windows if:
1. PHP `open_basedir` is set
2. `$name` is an absolute path

example:
```
ErrorException: is_file(): open_basedir restriction in effect.
File(C:/dev\ps_17\app/Resources/views/C:/dev/ps_17/mails/themes/modern/core/account.html.twig)
is not within the allowed path(s): (C:/dev)
in C:/dev\ps_17\vendor\twig\twig\src\Loader\FilesystemLoader.php:233
```

Issue presented in all major versions (1.x - 3.x).

Pull request description:
Fix: A template name cannot be an absolute path
fixes #3209, https://github.com/PrestaShop/PrestaShop/issues/20709

The source of this is in https://github.com/twigphp/Twig/blob/v3.3.0/src/Loader/FilesystemLoader.php#L212 which NEVER accepts an absolute name (path is always prefixed with path). As discussed in https://github.com/twigphp/Twig/issues/3209#issuecomment-814816613.

The original code emit php warning when `open_basedir` is set on Windows on NTS PHP build (because of PHP inconsistency between TS and NTS, see https://bugs.php.net/bug.php?id=78939). This PR fixes this issue and no warning is emitted.

This fix is important as Symfony relies on exception when absolute path is given in https://github.com/symfony/symfony/blob/v3.4.47/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php#L82.

Please merge and issue a patch release for every major Twig version.

Patch:
diff --git a/doc/filters/slice.rst b/doc/filters/slice.rst
index 8d7f8016..a36e01b7 100644
--- a/doc/filters/slice.rst
+++ b/doc/filters/slice.rst
@@ -68,5 +68,5 @@ Arguments
 
 .. _`Traversable`: https://secure.php.net/manual/en/class.traversable.php
 .. _`array_slice`: https://secure.php.net/array_slice
-.. _`mb_substr`:   https://secure.php.net/mb-substr
+.. _`mb_substr` :  https://secure.php.net/mb-substr
 .. _`substr`:      https://secure.php.net/substr
diff --git a/src/Loader/FilesystemLoader.php b/src/Loader/FilesystemLoader.php
index 7ca21458..a27a133c 100644
--- a/src/Loader/FilesystemLoader.php
+++ b/src/Loader/FilesystemLoader.php
@@ -292,6 +292,10 @@ class FilesystemLoader implements LoaderInterface, ExistsLoaderInterface, Source
             throw new LoaderError('A template name cannot contain NUL bytes.');
         }
 
+        if ($this->isAbsolutePath($name)) {
+            throw new LoaderError(sprintf('A template name cannot be an absolute path (%s).', $name));
+        }
+
         $name = ltrim($name, '/');
         $parts = explode('/', $name);
         $level = 0;


Test patch:
diff --git a/tests/Loader/FilesystemTest.php b/tests/Loader/FilesystemTest.php
index 3307a9b7..69680c8a 100644
--- a/tests/Loader/FilesystemTest.php
+++ b/tests/Loader/FilesystemTest.php
@@ -32,11 +32,13 @@ class FilesystemTest extends \PHPUnit\Framework\TestCase
     {
         $loader = new FilesystemLoader([__DIR__.'/../Fixtures']);
 
+        $this->expectException(LoaderError::class);
         try {
             $loader->getCacheKey($template);
-            $this->fail();
         } catch (LoaderError $e) {
             $this->assertStringNotContainsString('Unable to find template', $e->getMessage());
+
+            throw $e;
         }
     }
 
@@ -62,6 +64,14 @@ class FilesystemTest extends \PHPUnit\Framework\TestCase
             ['filters\\\\..\\\\..\\\\AutoloaderTest.php'],
             ['filters\\//../\\/\\..\\AutoloaderTest.php'],
             ['/../AutoloaderTest.php'],
+            ['/AutoloaderTest.php'],
+            ['\\AutoloaderTest.php'],
+            ['//AutoloaderTest.php'],
+            ['\\\\AutoloaderTest.php'],
+            ['/./AutoloaderTest.php'],
+            ['\\.\\AutoloaderTest.php'],
+            ['C:/AutoloaderTest.php'],
+            ['C:\\AutoloaderTest.php'],
         ];
     }