]> source.dussan.org Git - nextcloud-server.git/commitdiff
some file scanner performance improvements 31608/head
authorRobin Appelman <robin@icewind.nl>
Thu, 17 Mar 2022 15:05:52 +0000 (16:05 +0100)
committerRobin Appelman <robin@icewind.nl>
Thu, 17 Mar 2022 21:21:16 +0000 (22:21 +0100)
Signed-off-by: Robin Appelman <robin@icewind.nl>
lib/private/Files/Cache/Scanner.php
lib/private/Files/Filesystem.php
lib/private/Files/Storage/Common.php
lib/private/Files/Storage/Local.php

index bd8db2c8a12b3461829fa09b398445e87166973d..af412dd129ba320788a4978ce41db21bfebcdd3e 100644 (file)
@@ -36,7 +36,6 @@
 namespace OC\Files\Cache;
 
 use Doctrine\DBAL\Exception;
-use OC\Files\Filesystem;
 use OC\Files\Storage\Wrapper\Jail;
 use OC\Files\Storage\Wrapper\Encoding;
 use OC\Hooks\BasicEmitter;
@@ -140,8 +139,8 @@ class Scanner extends BasicEmitter implements IScanner {
                                return null;
                        }
                }
-               // only proceed if $file is not a partial file nor a blacklisted file
-               if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) {
+               // only proceed if $file is not a partial file, blacklist is handled by the storage
+               if (!self::isPartialFile($file)) {
 
                        //acquire a lock
                        if ($lock) {
index 1aedad93aa10edc80c73748284e50e050439c946..9db9252037ff7eadbd304e9bba599361ee15fa99 100644 (file)
@@ -66,6 +66,9 @@ class Filesystem {
 
        private static $listeningForProviders = false;
 
+       /** @var string[]|null */
+       private static $blacklist = null;
+
        /**
         * classname which used for hooks handling
         * used as signalclass in OC_Hooks::emit()
@@ -492,9 +495,12 @@ class Filesystem {
        public static function isFileBlacklisted($filename) {
                $filename = self::normalizePath($filename);
 
-               $blacklist = \OC::$server->getConfig()->getSystemValue('blacklisted_files', ['.htaccess']);
+               if (self::$blacklist === null) {
+                       self::$blacklist = \OC::$server->getConfig()->getSystemValue('blacklisted_files', ['.htaccess']);
+               }
+
                $filename = strtolower(basename($filename));
-               return in_array($filename, $blacklist);
+               return in_array($filename, self::$blacklist);
        }
 
        /**
index 7239c58a8a103b00135257b096101d3fb7a81cb6..8e7e56e6ca230b1876d10c93dbabbd5a841f4eb9 100644 (file)
@@ -52,6 +52,7 @@ use OC\Files\Storage\Wrapper\Jail;
 use OC\Files\Storage\Wrapper\Wrapper;
 use OCP\Files\EmptyFileNameException;
 use OCP\Files\FileNameTooLongException;
+use OCP\Files\ForbiddenException;
 use OCP\Files\GenericFileException;
 use OCP\Files\InvalidCharacterInPathException;
 use OCP\Files\InvalidDirectoryException;
@@ -702,6 +703,10 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage {
         * @inheritdoc
         */
        public function getMetaData($path) {
+               if (Filesystem::isFileBlacklisted($path)) {
+                       throw new ForbiddenException('Invalid path: ' . $path, false);
+               }
+
                $permissions = $this->getPermissions($path);
                if (!$permissions & \OCP\Constants::PERMISSION_READ) {
                        //can't read, nothing we can do
@@ -880,7 +885,7 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage {
                if (is_resource($dh)) {
                        $basePath = rtrim($directory, '/');
                        while (($file = readdir($dh)) !== false) {
-                               if (!Filesystem::isIgnoredDir($file) && !Filesystem::isFileBlacklisted($file)) {
+                               if (!Filesystem::isIgnoredDir($file)) {
                                        $childPath = $basePath . '/' . trim($file, '/');
                                        $metadata = $this->getMetaData($childPath);
                                        if ($metadata !== null) {
index 6406beaeebc0b52d9ef659a42ada71623f805f8a..34ab9a5fc9734d794adb34a90464439b7c495f07 100644 (file)
@@ -47,7 +47,9 @@ use OC\Files\Storage\Wrapper\Jail;
 use OCP\Constants;
 use OCP\Files\ForbiddenException;
 use OCP\Files\GenericFileException;
+use OCP\Files\IMimeTypeDetector;
 use OCP\Files\Storage\IStorage;
+use OCP\IConfig;
 use OCP\ILogger;
 
 /**
@@ -60,6 +62,10 @@ class Local extends \OC\Files\Storage\Common {
 
        protected $realDataDir;
 
+       private IConfig $config;
+
+       private IMimeTypeDetector $mimeTypeDetector;
+
        public function __construct($arguments) {
                if (!isset($arguments['datadir']) || !is_string($arguments['datadir'])) {
                        throw new \InvalidArgumentException('No data directory set for local storage');
@@ -76,6 +82,8 @@ class Local extends \OC\Files\Storage\Common {
                        $this->datadir .= '/';
                }
                $this->dataDirLength = strlen($this->realDataDir);
+               $this->config = \OC::$server->get(IConfig::class);
+               $this->mimeTypeDetector = \OC::$server->get(IMimeTypeDetector::class);
        }
 
        public function __destruct() {
@@ -155,6 +163,9 @@ class Local extends \OC\Files\Storage\Common {
                        $statResult['size'] = $filesize;
                        $statResult[7] = $filesize;
                }
+               if (is_array($statResult)) {
+                       $statResult['full_path'] = $fullPath;
+               }
                return $statResult;
        }
 
@@ -181,15 +192,14 @@ class Local extends \OC\Files\Storage\Common {
                }
 
                if (!($path === '' || $path === '/')) { // deletable depends on the parents unix permissions
-                       $fullPath = $this->getSourcePath($path);
-                       $parent = dirname($fullPath);
+                       $parent = dirname($stat['full_path']);
                        if (is_writable($parent)) {
                                $permissions += Constants::PERMISSION_DELETE;
                        }
                }
 
                $data = [];
-               $data['mimetype'] = $isDir ? 'httpd/unix-directory' : \OC::$server->getMimeTypeDetector()->detectPath($path);
+               $data['mimetype'] = $isDir ? 'httpd/unix-directory' : $this->mimeTypeDetector->detectPath($path);
                $data['mtime'] = $stat['mtime'];
                if ($data['mtime'] === false) {
                        $data['mtime'] = time();
@@ -450,7 +460,7 @@ class Local extends \OC\Files\Storage\Common {
 
                $fullPath = $this->datadir . $path;
                $currentPath = $path;
-               $allowSymlinks = \OC::$server->getConfig()->getSystemValue('localstorage.allowsymlinks', false);
+               $allowSymlinks = $this->config->getSystemValue('localstorage.allowsymlinks', false);
                if ($allowSymlinks || $currentPath === '') {
                        return $fullPath;
                }