diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php index 5e33ad235a..16b15aa6b3 100644 --- a/lib/private/Files/Cache/QuerySearchHelper.php +++ b/lib/private/Files/Cache/QuerySearchHelper.php @@ -166,6 +166,9 @@ class QuerySearchHelper { $field = 'tag.category'; } elseif ($field === 'fileid') { $field = 'file.fileid'; + } elseif ($field === 'path' && $type === ISearchComparison::COMPARE_EQUAL) { + $field = 'path_hash'; + $value = md5((string)$value); } return [$field, $value, $type]; } diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php index 6136c278c3..54cb578bb4 100644 --- a/lib/private/Files/Cache/Wrapper/CacheJail.php +++ b/lib/private/Files/Cache/Wrapper/CacheJail.php @@ -239,7 +239,10 @@ class CacheJail extends CacheWrapper { $query = $this->getQueryBuilder(); $query->selectFileCache() ->whereStorageId() - ->andWhere($query->expr()->like('path', $query->createNamedParameter($this->getRoot() . '/%'))) + ->andWhere($query->expr()->orX( + $query->expr()->like('path', $query->createNamedParameter($this->getRoot() . '/%')), + $query->expr()->eq('path_hash', $query->createNamedParameter(md5($this->getRoot()))), + )) ->andWhere($query->expr()->iLike('name', $query->createNamedParameter($pattern))); $result = $query->execute(); @@ -264,7 +267,10 @@ class CacheJail extends CacheWrapper { $query = $this->getQueryBuilder(); $query->selectFileCache() ->whereStorageId() - ->andWhere($query->expr()->like('path', $query->createNamedParameter($this->getRoot() . '/%'))); + ->andWhere($query->expr()->orX( + $query->expr()->like('path', $query->createNamedParameter($this->getRoot() . '/%')), + $query->expr()->eq('path_hash', $query->createNamedParameter(md5($this->getRoot()))), + )); if (strpos($mimetype, '/')) { $query->andWhere($query->expr()->eq('mimetype', $query->createNamedParameter($mimeId, IQueryBuilder::PARAM_INT))); @@ -288,9 +294,14 @@ class CacheJail extends CacheWrapper { 'path', $this->getRoot() . '/%' ); + $rootFilter = new SearchComparison( + ISearchComparison::COMPARE_EQUAL, + 'path', + $this->getRoot() + ); $operation = new SearchBinaryOperator( ISearchBinaryOperator::OPERATOR_AND, - [$prefixFilter, $query->getSearchOperation()] + [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [$prefixFilter, $rootFilter]) , $query->getSearchOperation()] ); $simpleQuery = new SearchQuery($operation, 0, 0, $query->getOrder(), $query->getUser()); $results = $this->getCache()->searchQuery($simpleQuery); diff --git a/tests/lib/Files/Cache/Wrapper/CacheJailTest.php b/tests/lib/Files/Cache/Wrapper/CacheJailTest.php index 83173efd3b..de54333312 100644 --- a/tests/lib/Files/Cache/Wrapper/CacheJailTest.php +++ b/tests/lib/Files/Cache/Wrapper/CacheJailTest.php @@ -37,6 +37,7 @@ class CacheJailTest extends CacheTest { } public function testSearchOutsideJail() { + $this->storage->getScanner()->scan(''); $file1 = 'foo/foobar'; $file2 = 'folder/foobar'; $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; @@ -49,9 +50,18 @@ class CacheJailTest extends CacheTest { $result = $this->cache->search('%foobar%'); $this->assertCount(1, $result); $this->assertEquals('foobar', $result[0]['path']); + + $result = $this->cache->search('%foo%'); + $this->assertCount(2, $result); + usort($result, function ($a, $b) { + return $a['path'] <=> $b['path']; + }); + $this->assertEquals('', $result[0]['path']); + $this->assertEquals('foobar', $result[1]['path']); } public function testSearchMimeOutsideJail() { + $this->storage->getScanner()->scan(''); $file1 = 'foo/foobar'; $file2 = 'folder/foobar'; $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; @@ -67,6 +77,7 @@ class CacheJailTest extends CacheTest { } public function testSearchQueryOutsideJail() { + $this->storage->getScanner()->scan(''); $file1 = 'foo/foobar'; $file2 = 'folder/foobar'; $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; @@ -76,11 +87,15 @@ class CacheJailTest extends CacheTest { $user = new User('foo', null, $this->createMock(EventDispatcherInterface::class)); $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), 10, 0, [], $user); - $this->assertCount(2, $this->sourceCache->searchQuery($query)); + $result = $this->cache->searchQuery($query); - $result = $this->cache->search('%foobar%'); $this->assertCount(1, $result); $this->assertEquals('foobar', $result[0]['path']); + + $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foo'), 10, 0, [], $user); + $result = $this->cache->searchQuery($query); + $this->assertCount(1, $result); + $this->assertEquals('', $result[0]['path']); } public function testClearKeepEntriesOutsideJail() {