Merge pull request #23885 from nextcloud/backport/23097/stable19

[stable19] Restrict query when searching for versions of trashbin files
This commit is contained in:
John Molakvoæ 2020-11-04 15:40:30 +01:00 committed by GitHub
commit 2223a11739
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 43 additions and 14 deletions

View File

@ -43,6 +43,9 @@
namespace OCA\Files_Trashbin; 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\Filesystem;
use OC\Files\ObjectStore\ObjectStoreStorage; use OC\Files\ObjectStore\ObjectStoreStorage;
use OC\Files\View; use OC\Files\View;
@ -917,33 +920,59 @@ class Trashbin {
$view = new View('/' . $user . '/files_trashbin/versions'); $view = new View('/' . $user . '/files_trashbin/versions');
$versions = []; $versions = [];
//force rescan of versions, local storage may not have updated the cache
if (!self::$scannedVersions) {
/** @var \OC\Files\Storage\Storage $storage */ /** @var \OC\Files\Storage\Storage $storage */
[$storage,] = $view->resolvePath('/'); [$storage,] = $view->resolvePath('/');
//force rescan of versions, local storage may not have updated the cache
if (!self::$scannedVersions) {
$storage->getScanner()->scan('files_trashbin/versions'); $storage->getScanner()->scan('files_trashbin/versions');
self::$scannedVersions = true; self::$scannedVersions = true;
} }
$pattern = \OC::$server->getDatabaseConnection()->escapeLikeParameter(basename($filename));
if ($timestamp) { if ($timestamp) {
// fetch for old versions // fetch for old versions
$matches = $view->searchRaw($filename . '.v%.d' . $timestamp); $escapedTimestamp = \OC::$server->getDatabaseConnection()->escapeLikeParameter($timestamp);
$offset = -strlen($timestamp) - 2; $pattern .= '.v%.d' . $escapedTimestamp;
$offset = -strlen($escapedTimestamp) - 2;
} else { } else {
$matches = $view->searchRaw($filename . '.v%'); $pattern .= '.v%';
} }
if (is_array($matches)) { // 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) { foreach ($matches as $ma) {
if ($timestamp) { if ($timestamp) {
$parts = explode('.v', substr($ma['path'], 0, $offset)); $parts = explode('.v', substr($ma['path'], 0, $offset));
$versions[] = end($parts); $versions[] = end($parts);
} else { } else {
$parts = explode('.v', $ma); $parts = explode('.v', $ma['path']);
$versions[] = end($parts); $versions[] = end($parts);
} }
} }
}
return $versions; return $versions;
} }