]> source.dussan.org Git - nextcloud-server.git/commitdiff
Restrict query when searching for versions of trashbin files 23097/head
authorJulius Härtl <jus@bitgrid.net>
Tue, 29 Sep 2020 15:02:53 +0000 (17:02 +0200)
committerJulius Härtl <jus@bitgrid.net>
Wed, 14 Oct 2020 14:38:30 +0000 (16:38 +0200)
Signed-off-by: Julius Härtl <jus@bitgrid.net>
apps/files_trashbin/lib/Trashbin.php

index 2626f439d11ca5fb7bfec1f94b9bfbc91e33b318..a18cac25bb9bff8a4254934923047357e48aa5ee 100644 (file)
@@ -44,6 +44,9 @@
 
 namespace OCA\Files_Trashbin;
 
+use OC\Files\Cache\Cache;
+use OC\Files\Cache\CacheEntry;
+use OC\Files\Cache\CacheQueryBuilder;
 use OC\Files\Filesystem;
 use OC\Files\ObjectStore\ObjectStoreStorage;
 use OC\Files\View;
@@ -926,33 +929,59 @@ class Trashbin {
                $view = new View('/' . $user . '/files_trashbin/versions');
                $versions = [];
 
+               /** @var \OC\Files\Storage\Storage $storage */
+               [$storage,] = $view->resolvePath('/');
+
                //force rescan of versions, local storage may not have updated the cache
                if (!self::$scannedVersions) {
-                       /** @var \OC\Files\Storage\Storage $storage */
-                       [$storage,] = $view->resolvePath('/');
                        $storage->getScanner()->scan('files_trashbin/versions');
                        self::$scannedVersions = true;
                }
 
+               $pattern = \OC::$server->getDatabaseConnection()->escapeLikeParameter(basename($filename));
                if ($timestamp) {
                        // fetch for old versions
-                       $matches = $view->searchRaw($filename . '.v%.d' . $timestamp);
-                       $offset = -strlen($timestamp) - 2;
+                       $escapedTimestamp = \OC::$server->getDatabaseConnection()->escapeLikeParameter($timestamp);
+                       $pattern .= '.v%.d' . $escapedTimestamp;
+                       $offset = -strlen($escapedTimestamp) - 2;
                } else {
-                       $matches = $view->searchRaw($filename . '.v%');
+                       $pattern .= '.v%';
                }
 
-               if (is_array($matches)) {
-                       foreach ($matches as $ma) {
-                               if ($timestamp) {
-                                       $parts = explode('.v', substr($ma['path'], 0, $offset));
-                                       $versions[] = end($parts);
-                               } else {
-                                       $parts = explode('.v', $ma);
-                                       $versions[] = end($parts);
-                               }
+               // Manually fetch all versions from the file cache to be able to filter them by their parent
+               $cache = $storage->getCache('');
+               $query = new CacheQueryBuilder(
+                       \OC::$server->getDatabaseConnection(),
+                       \OC::$server->getSystemConfig(),
+                       \OC::$server->getLogger(),
+                       $cache
+               );
+               $normalizedParentPath = ltrim(Filesystem::normalizePath(dirname('files_trashbin/versions/'. $filename)), '/');
+               $parentId = $cache->getId($normalizedParentPath);
+               if ($parentId === -1) {
+                       return [];
+               }
+
+               $query->selectFileCache()
+                       ->whereStorageId()
+                       ->andWhere($query->expr()->eq('parent', $query->createNamedParameter($parentId)))
+                       ->andWhere($query->expr()->iLike('name', $query->createNamedParameter($pattern)));
+
+               /** @var CacheEntry[] $matches */
+               $matches = array_map(function (array $data) {
+                       return Cache::cacheEntryFromData($data, \OC::$server->getMimeTypeLoader());
+               }, $query->execute()->fetchAll());
+
+               foreach ($matches as $ma) {
+                       if ($timestamp) {
+                               $parts = explode('.v', substr($ma['path'], 0, $offset));
+                               $versions[] = end($parts);
+                       } else {
+                               $parts = explode('.v', $ma['path']);
+                               $versions[] = end($parts);
                        }
                }
+
                return $versions;
        }