From 5d6c90361c680f3d0e05bc1c06a31f0538465c18 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 25 Jan 2017 11:51:38 +1300 Subject: [PATCH] BUG Ensure root path of any local adapter is safely created and mapped from symlink Fixes https://github.com/silverstripe/silverstripe-asset-admin/issues/362 --- src/Assets/Flysystem/AssetAdapter.php | 5 +++- src/Assets/Flysystem/PublicAssetAdapter.php | 31 ++++++++++++--------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/Assets/Flysystem/AssetAdapter.php b/src/Assets/Flysystem/AssetAdapter.php index ddfa63911..8c4173121 100644 --- a/src/Assets/Flysystem/AssetAdapter.php +++ b/src/Assets/Flysystem/AssetAdapter.php @@ -5,6 +5,7 @@ namespace SilverStripe\Assets\Flysystem; use League\Flysystem\Adapter\Local; use League\Flysystem\Config as FlysystemConfig; use SilverStripe\Assets\File; +use SilverStripe\Assets\Filesystem; use SilverStripe\Core\Config\Config; use SilverStripe\ORM\ArrayList; use SilverStripe\View\ArrayData; @@ -43,8 +44,10 @@ class AssetAdapter extends Local public function __construct($root = null, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS) { - // Get root path + // Get root path, and ensure that this exists and is safe $root = $this->findRoot($root); + Filesystem::makeFolder($root); + $root = realpath($root); // Override permissions with config $permissions = Config::inst()->get(get_class($this), 'file_permissions'); diff --git a/src/Assets/Flysystem/PublicAssetAdapter.php b/src/Assets/Flysystem/PublicAssetAdapter.php index 09b61c9b7..2f132a74b 100644 --- a/src/Assets/Flysystem/PublicAssetAdapter.php +++ b/src/Assets/Flysystem/PublicAssetAdapter.php @@ -7,6 +7,13 @@ use SilverStripe\Control\Director; class PublicAssetAdapter extends AssetAdapter implements PublicAdapter { + /** + * Prefix between the root url and base of the assets folder + * Used for generating public urls + * + * @var string + */ + protected $parentUrlPrefix = null; /** * Server specific configuration necessary to block http traffic to a local folder @@ -26,11 +33,18 @@ class PublicAssetAdapter extends AssetAdapter implements PublicAdapter protected function findRoot($root) { if ($root) { - return parent::findRoot($root); + $path = parent::findRoot($root); + } else { + $path = ASSETS_PATH; } - // Empty root will set the path to assets - return ASSETS_PATH; + // Detect segment between root directory and assets root + if (stripos($path, BASE_PATH) === 0) { + $this->parentUrlPrefix = substr($path, strlen(BASE_PATH)); + } else { + $this->parentUrlPrefix = ASSETS_DIR; + } + return $path; } /** @@ -41,15 +55,6 @@ class PublicAssetAdapter extends AssetAdapter implements PublicAdapter */ public function getPublicUrl($path) { - $rootPath = realpath(BASE_PATH); - $filesPath = realpath($this->pathPrefix); - - if (stripos($filesPath, $rootPath) === 0) { - $dir = substr($filesPath, strlen($rootPath)); - return Controller::join_links(Director::baseURL(), $dir, $path); - } - - // File outside of webroot can't be used - return null; + return Controller::join_links(Director::baseURL(), $this->parentUrlPrefix, $path); } }