From 8cc27e9053220b0ccce0b5fdd41b2ea3b66b5f20 Mon Sep 17 00:00:00 2001 From: Ivo Valchev Date: Wed, 24 Feb 2021 11:20:54 +0100 Subject: [PATCH 1/2] From Library button on Windows generates the correct URL --- .../Backend/Async/FileListingController.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Controller/Backend/Async/FileListingController.php b/src/Controller/Backend/Async/FileListingController.php index 0a254ac5e..c17584d44 100644 --- a/src/Controller/Backend/Async/FileListingController.php +++ b/src/Controller/Backend/Async/FileListingController.php @@ -5,6 +5,7 @@ namespace Bolt\Controller\Backend\Async; use Bolt\Configuration\Config; +use Bolt\Utils\PathCanonicalize; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; use Symfony\Component\Finder\Finder; use Symfony\Component\HttpFoundation\JsonResponse; @@ -12,6 +13,7 @@ use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Annotation\Route; use Tightenco\Collect\Support\Collection; +use Webmozart\PathUtil\Path; /** * @Security("is_granted('ROLE_ADMIN')") @@ -24,10 +26,14 @@ class FileListingController implements AsyncZoneInterface /** @var Request */ private $request; - public function __construct(Config $config, RequestStack $requestStack) + /** @var string */ + private $publicPath; + + public function __construct(Config $config, RequestStack $requestStack, string $projectDir, string $publicFolder) { $this->config = $config; $this->request = $requestStack->getCurrentRequest(); + $this->publicPath = $projectDir . DIRECTORY_SEPARATOR . $publicFolder; } /** @@ -38,7 +44,12 @@ public function index(): JsonResponse $locationName = $this->request->query->get('location', 'files'); $type = $this->request->query->get('type', ''); - $path = $this->config->getPath($locationName, true); + // @todo: config->getPath does not return the correct relative URL. + // Hence, we use the Path::makeRelative. Fix this once config generates the correct relative path. + $relativeLocation = Path::makeRelative($this->config->getPath($locationName, false), $this->publicPath); + + // Do not allow any path outside of the public directory. + $path = PathCanonicalize::canonicalize($this->publicPath, $relativeLocation); $files = $this->getFilesIndex($path, $type); @@ -57,8 +68,8 @@ private function getFilesIndex(string $path, string $type): Collection foreach ($this->findFiles($path, $glob) as $file) { $files[] = [ - 'group' => $file->getRelativePath(), - 'value' => $file->getRelativePathname(), + 'group' => Path::canonicalize($file->getRelativePath()), + 'value' => Path::canonicalize($file->getRelativePathname()), 'text' => $file->getFilename(), ]; } From 9aa389633aac9d9c91509ca057f88949d9cf87d0 Mon Sep 17 00:00:00 2001 From: Ivo Valchev Date: Wed, 24 Feb 2021 11:20:54 +0100 Subject: [PATCH 2/2] From Library button on Windows generates the correct URL --- .../Backend/Async/FileListingController.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Controller/Backend/Async/FileListingController.php b/src/Controller/Backend/Async/FileListingController.php index 0a254ac5e..c17584d44 100644 --- a/src/Controller/Backend/Async/FileListingController.php +++ b/src/Controller/Backend/Async/FileListingController.php @@ -5,6 +5,7 @@ namespace Bolt\Controller\Backend\Async; use Bolt\Configuration\Config; +use Bolt\Utils\PathCanonicalize; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; use Symfony\Component\Finder\Finder; use Symfony\Component\HttpFoundation\JsonResponse; @@ -12,6 +13,7 @@ use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Annotation\Route; use Tightenco\Collect\Support\Collection; +use Webmozart\PathUtil\Path; /** * @Security("is_granted('ROLE_ADMIN')") @@ -24,10 +26,14 @@ class FileListingController implements AsyncZoneInterface /** @var Request */ private $request; - public function __construct(Config $config, RequestStack $requestStack) + /** @var string */ + private $publicPath; + + public function __construct(Config $config, RequestStack $requestStack, string $projectDir, string $publicFolder) { $this->config = $config; $this->request = $requestStack->getCurrentRequest(); + $this->publicPath = $projectDir . DIRECTORY_SEPARATOR . $publicFolder; } /** @@ -38,7 +44,12 @@ public function index(): JsonResponse $locationName = $this->request->query->get('location', 'files'); $type = $this->request->query->get('type', ''); - $path = $this->config->getPath($locationName, true); + // @todo: config->getPath does not return the correct relative URL. + // Hence, we use the Path::makeRelative. Fix this once config generates the correct relative path. + $relativeLocation = Path::makeRelative($this->config->getPath($locationName, false), $this->publicPath); + + // Do not allow any path outside of the public directory. + $path = PathCanonicalize::canonicalize($this->publicPath, $relativeLocation); $files = $this->getFilesIndex($path, $type); @@ -57,8 +68,8 @@ private function getFilesIndex(string $path, string $type): Collection foreach ($this->findFiles($path, $glob) as $file) { $files[] = [ - 'group' => $file->getRelativePath(), - 'value' => $file->getRelativePathname(), + 'group' => Path::canonicalize($file->getRelativePath()), + 'value' => Path::canonicalize($file->getRelativePathname()), 'text' => $file->getFilename(), ]; }