diff options
author | Julius Härtl <jus@bitgrid.net> | 2020-09-29 17:02:53 +0200 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2020-10-14 16:38:30 +0200 |
commit | 2616a784c9fb9c67444682b9257e128aecd4bcbd (patch) | |
tree | e7bb431ae6e1726925e40e2094d155a0a4ca4e40 /apps/files_trashbin | |
parent | a41b273bcd1a99e5db1ccf63f677a3fb459505d7 (diff) | |
download | nextcloud-server-2616a784c9fb9c67444682b9257e128aecd4bcbd.tar.gz nextcloud-server-2616a784c9fb9c67444682b9257e128aecd4bcbd.zip |
Restrict query when searching for versions of trashbin files
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'apps/files_trashbin')
-rw-r--r-- | apps/files_trashbin/lib/Trashbin.php | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/apps/files_trashbin/lib/Trashbin.php b/apps/files_trashbin/lib/Trashbin.php index 2626f439d11..a18cac25bb9 100644 --- a/apps/files_trashbin/lib/Trashbin.php +++ b/apps/files_trashbin/lib/Trashbin.php @@ -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; } |