diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php index 2b785ea47a..c21950343c 100644 --- a/lib/private/Files/Node/Folder.php +++ b/lib/private/Files/Node/Folder.php @@ -33,6 +33,7 @@ namespace OC\Files\Node; use OC\DB\QueryBuilder\Literal; use OC\Files\Mount\MountPoint; +use OC\Files\Search\SearchBinaryOperator; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; use OC\Files\Storage\Wrapper\Jail; @@ -45,6 +46,7 @@ use OCP\Files\FileInfo; use OCP\Files\Mount\IMountPoint; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCP\Files\Search\ISearchBinaryOperator; use OCP\Files\Search\ISearchComparison; use OCP\Files\Search\ISearchOperator; use OCP\Files\Search\ISearchQuery; @@ -253,17 +255,6 @@ class Folder extends Node implements \OCP\Files\Folder { throw new \InvalidArgumentException('searching by owner is only allows on the users home folder'); } - $subQueryLimit = $query->getLimit() > 0 ? $query->getLimit() + $query->getOffset() : PHP_INT_MAX; - $subQueryOffset = $query->getOffset(); - $noLimitQuery = new SearchQuery( - $query->getSearchOperation(), - $subQueryLimit, - 0, - $query->getOrder(), - $query->getUser() - ); - - $files = []; $rootLength = strlen($this->path); $mount = $this->root->getMount($this->path); $storage = $mount->getStorage(); @@ -272,20 +263,33 @@ class Folder extends Node implements \OCP\Files\Folder { if ($internalPath !== '') { $internalPath = $internalPath . '/'; } - $internalRootLength = strlen($internalPath); + + $subQueryLimit = $query->getLimit() > 0 ? $query->getLimit() + $query->getOffset() : PHP_INT_MAX; + $subQueryOffset = $query->getOffset(); + $rootQuery = new SearchQuery( + new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [ + new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', $internalPath . '%'), + $query->getSearchOperation(), + ] + ), + $subQueryLimit, + 0, + $query->getOrder(), + $query->getUser() + ); + + $files = []; $cache = $storage->getCache(''); - $results = $cache->searchQuery($noLimitQuery); + $results = $cache->searchQuery($rootQuery); $count = count($results); $results = array_slice($results, $subQueryOffset, $subQueryLimit); $subQueryOffset = max(0, $subQueryOffset - $count); $subQueryLimit = max(0, $subQueryLimit - $count); foreach ($results as $result) { - if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) { - $files[] = $this->cacheEntryToFileInfo($mount, '', $internalPath, $result); - } + $files[] = $this->cacheEntryToFileInfo($mount, '', $internalPath, $result); } if (!$limitToHome) { @@ -330,7 +334,7 @@ class Folder extends Node implements \OCP\Files\Folder { private function cacheEntryToFileInfo(IMountPoint $mount, string $appendRoot, string $trimRoot, ICacheEntry $cacheEntry): FileInfo { $trimLength = strlen($trimRoot); $cacheEntry['internalPath'] = $cacheEntry['path']; - $cacheEntry['path'] = $appendRoot . substr($cacheEntry['path'], $trimLength); + $cacheEntry['path'] = $appendRoot . substr($cacheEntry['path'], $trimLength); return new \OC\Files\FileInfo($this->path . '/' . $cacheEntry['path'], $mount->getStorage(), $cacheEntry['internalPath'], $cacheEntry, $mount); } diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php index 339a77edcc..39dcffe5ae 100644 --- a/tests/lib/Files/Node/FolderTest.php +++ b/tests/lib/Files/Node/FolderTest.php @@ -354,7 +354,6 @@ class FolderTest extends NodeTest { $cache->method('searchQuery') ->willReturn([ new CacheEntry(['fileid' => 3, 'path' => 'files/foo', 'name' => 'qwerty', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']), - new CacheEntry(['fileid' => 3, 'path' => 'files_trashbin/foo2.d12345', 'name' => 'foo2.d12345', 'size' => 200, 'mtime' => 55, 'mimetype' => 'text/plain']), ]); $root->method('getMountsIn')