From 0c19c5c65ad9cd76f0a0a884de4e23913fe1da63 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Mon, 22 Nov 2021 13:37:55 +0100 Subject: [PATCH] Fix search results filtering Signed-off-by: Carl Schwan --- lib/private/Files/Cache/Cache.php | 10 +++---- lib/private/Files/Cache/Wrapper/CacheJail.php | 27 ++++++++++++++----- .../Files/Cache/Wrapper/CacheWrapper.php | 14 +++++++--- .../lib/Files/Cache/Wrapper/CacheJailTest.php | 24 +++++++++++++++++ 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index 74a386b3f9e..cd8e6a5e3a8 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -173,14 +173,10 @@ class Cache implements ICache { } /** - * Create a CacheEntry from database row - * - * @param array $data - * @param IMimeTypeLoader $mimetypeLoader - * @return CacheEntry + * Helper method that creates a CacheEntry from a database row. */ - public static function cacheEntryFromData($data, IMimeTypeLoader $mimetypeLoader) { - //fix types + public static function cacheEntryFromData(array $data, IMimeTypeLoader $mimetypeLoader): ICacheEntry { + // Fix types $data['fileid'] = (int)$data['fileid']; $data['parent'] = (int)$data['parent']; $data['size'] = 0 + $data['size']; diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php index 7b2942b02b9..e1e5050905d 100644 --- a/lib/private/Files/Cache/Wrapper/CacheJail.php +++ b/lib/private/Files/Cache/Wrapper/CacheJail.php @@ -107,8 +107,8 @@ class CacheJail extends CacheWrapper { } /** - * @param ICacheEntry|array $entry - * @return array + * @param ICacheEntry $entry + * @return ICacheEntry */ protected function formatCacheEntry($entry) { if (isset($entry['path'])) { @@ -118,7 +118,7 @@ class CacheJail extends CacheWrapper { } /** - * get the stored metadata of a file or folder + * Get the stored metadata of a file or folder * * @param string /int $file * @return ICacheEntry|false @@ -229,10 +229,25 @@ class CacheJail extends CacheWrapper { } private function formatSearchResults($results) { - return array_map(function ($entry) { + $finalResult = []; + foreach ($results as $entry) { + // Filter not accessible entries (e.g. some groupfolder entries when ACLs are enabled) + $cacheWrapper = $this; + while (($cacheWrapper instanceof CacheWrapper) && $entry !== false) { + if (!($cacheWrapper instanceof CacheJail)) { // We apply the jail at the end + $entry = $cacheWrapper->formatCacheEntry($entry); + } + $cacheWrapper = $cacheWrapper->getCache(); + } + if ($entry === false) { + continue; + } + + // Unjailed the path (remove __groupfolder/ prefix) $entry['path'] = $this->getJailedPath($entry['path'], $this->getGetUnjailedRoot()); - return $entry; - }, $results); + $finalResult[] = $entry; + } + return $finalResult; } /** diff --git a/lib/private/Files/Cache/Wrapper/CacheWrapper.php b/lib/private/Files/Cache/Wrapper/CacheWrapper.php index 4901a530799..4b97e21f2e1 100644 --- a/lib/private/Files/Cache/Wrapper/CacheWrapper.php +++ b/lib/private/Files/Cache/Wrapper/CacheWrapper.php @@ -53,7 +53,7 @@ class CacheWrapper extends Cache { } /** - * Make it easy for wrappers to modify every returned cache entry + * Makes it easy for wrappers to modify every returned cache entry * * @param ICacheEntry $entry * @return ICacheEntry @@ -224,7 +224,9 @@ class CacheWrapper extends Cache { */ public function search($pattern) { $results = $this->getCache()->search($pattern); - return array_map([$this, 'formatCacheEntry'], $results); + return array_filter(array_map([$this, 'formatCacheEntry'], $results), function ($entry) { + return $entry !== false; + }); } /** @@ -235,12 +237,16 @@ class CacheWrapper extends Cache { */ public function searchByMime($mimetype) { $results = $this->getCache()->searchByMime($mimetype); - return array_map([$this, 'formatCacheEntry'], $results); + return array_filter(array_map([$this, 'formatCacheEntry'], $results), function ($entry) { + return $entry !== false; + }); } public function searchQuery(ISearchQuery $query) { $results = $this->getCache()->searchQuery($query); - return array_map([$this, 'formatCacheEntry'], $results); + return array_filter(array_map([$this, 'formatCacheEntry'], $results), function ($entry) { + return $entry !== false; + }); } /** diff --git a/tests/lib/Files/Cache/Wrapper/CacheJailTest.php b/tests/lib/Files/Cache/Wrapper/CacheJailTest.php index 4c3dce74087..0891727e8b6 100644 --- a/tests/lib/Files/Cache/Wrapper/CacheJailTest.php +++ b/tests/lib/Files/Cache/Wrapper/CacheJailTest.php @@ -9,6 +9,7 @@ namespace Test\Files\Cache\Wrapper; use OC\Files\Cache\Wrapper\CacheJail; +use OC\Files\Cache\Wrapper\CacheWrapper; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; use OC\User\User; @@ -201,6 +202,29 @@ class CacheJailTest extends CacheTest { $this->assertEquals('asd', $result[0]['path']); } + public function testNotAuthorized() { + $this->storage->getScanner()->scan(''); + $file1 = 'foo'; + $file2 = 'foo/bar'; + $file3 = 'foo/bar/asd'; + $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; + + $this->sourceCache->put($file1, $data1); + $this->sourceCache->put($file2, $data1); + $this->sourceCache->put($file3, $data1); + + $nested = new class($this->cache) extends CacheWrapper { + protected function formatCacheEntry($entry) { + return false; + } + }; + + $nested = new \OC\Files\Cache\Wrapper\CacheJail($nested, 'bar'); + + $result = $nested->search('%asd%'); + $this->assertCount(0, $result); + } + public function testRootJail() { $this->storage->getScanner()->scan(''); $file1 = 'foo';