aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2025-01-27 01:24:41 +0100
committerFerdinand Thiessen <opensource@fthiessen.de>2025-01-27 01:25:36 +0100
commit53815b3f5d81ba3b8c5db534fcfa90c41a23d1dc (patch)
tree838bbefdc2bdff3fa702836fd040bb4c53befe2c
parenta13b52794ce70e59a784e3e5432650789d8f6292 (diff)
downloadnextcloud-server-53815b3f5d81ba3b8c5db534fcfa90c41a23d1dc.tar.gz
nextcloud-server-53815b3f5d81ba3b8c5db534fcfa90c41a23d1dc.zip
fixup! fix: Harden files scanner for invalid null access
-rw-r--r--apps/files_sharing/lib/Cache.php4
-rw-r--r--lib/private/Files/Cache/Cache.php28
-rw-r--r--lib/private/Files/Cache/Scanner.php4
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheJail.php35
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheWrapper.php15
5 files changed, 48 insertions, 38 deletions
diff --git a/apps/files_sharing/lib/Cache.php b/apps/files_sharing/lib/Cache.php
index 372dde198a0..350f4718712 100644
--- a/apps/files_sharing/lib/Cache.php
+++ b/apps/files_sharing/lib/Cache.php
@@ -63,12 +63,12 @@ class Cache extends CacheJail {
/** @var Jail $currentStorage */
$absoluteRoot = $currentStorage->getJailedPath($absoluteRoot);
}
- $this->root = $absoluteRoot;
+ $this->root = $absoluteRoot ?? '';
}
return $this->root;
}
- protected function getGetUnjailedRoot() {
+ protected function getGetUnjailedRoot(): string {
return $this->sourceRootInfo->getPath();
}
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index 5dcce6d8bbb..7fbb625050b 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -109,7 +109,7 @@ class Cache implements ICache {
/**
* get the stored metadata of a file or folder
*
- * @param string | int $file either the path of a file or folder or the file id for a file or folder
+ * @param string|int $file either the path of a file or folder or the file id for a file or folder
* @return ICacheEntry|false the cache entry as array or false if the file is not found in the cache
*/
public function get($file) {
@@ -131,15 +131,17 @@ class Cache implements ICache {
$data = $result->fetch();
$result->closeCursor();
- //merge partial data
- if (!$data && is_string($file) && isset($this->partial[$file])) {
- return $this->partial[$file];
- } elseif (!$data) {
- return $data;
- } else {
+ if ($data !== false) {
$data['metadata'] = $metadataQuery->extractMetadata($data)->asArray();
return self::cacheEntryFromData($data, $this->mimetypeLoader);
+ } else {
+ //merge partial data
+ if (is_string($file) && isset($this->partial[$file])) {
+ return $this->partial[$file];
+ }
}
+
+ return false;
}
/**
@@ -886,19 +888,23 @@ class Cache implements ICache {
/**
* Re-calculate the folder size and the size of all parent folders
*
- * @param string|boolean $path
- * @param array $data (optional) meta data of the folder
+ * @param array|ICacheEntry|null $data (optional) meta data of the folder
*/
- public function correctFolderSize($path, $data = null, $isBackgroundScan = false) {
+ public function correctFolderSize(string $path, $data = null, bool $isBackgroundScan = false): void {
$this->calculateFolderSize($path, $data);
+
if ($path !== '') {
$parent = dirname($path);
if ($parent === '.' || $parent === '/') {
$parent = '';
}
+
if ($isBackgroundScan) {
$parentData = $this->get($parent);
- if ($parentData['size'] !== -1 && $this->getIncompleteChildrenCount($parentData['fileid']) === 0) {
+ if ($parentData !== false
+ && $parentData['size'] !== -1
+ && $this->getIncompleteChildrenCount($parentData['fileid']) === 0
+ ) {
$this->correctFolderSize($parent, $parentData, $isBackgroundScan);
}
} else {
diff --git a/lib/private/Files/Cache/Scanner.php b/lib/private/Files/Cache/Scanner.php
index 2bf1203955e..404c9310108 100644
--- a/lib/private/Files/Cache/Scanner.php
+++ b/lib/private/Files/Cache/Scanner.php
@@ -108,7 +108,7 @@ class Scanner extends BasicEmitter implements IScanner {
* @param string $file
* @param int $reuseExisting
* @param int $parentId
- * @param array|null|false $cacheData existing data in the cache for the file to be scanned
+ * @param array|CacheEntry|null|false $cacheData existing data in the cache for the file to be scanned
* @param bool $lock set to false to disable getting an additional read lock during scanning
* @param array|null $data the metadata for the file, as returned by the storage
* @return array|null an array of metadata of the scanned file
@@ -207,7 +207,7 @@ class Scanner extends BasicEmitter implements IScanner {
* i.e. get all the values in $data that are not present in the cache already
*
* We need the OC implementation for usage of "getData" method below.
- * @var \OC\Files\Cache\CacheEntry $cacheData
+ * @var \OC\Files\Cache\CacheEntry $cacheData
*/
$newData = $this->array_diff_assoc_multi($data, $cacheData->getData());
diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php
index ea0f992114a..87952543c23 100644
--- a/lib/private/Files/Cache/Wrapper/CacheJail.php
+++ b/lib/private/Files/Cache/Wrapper/CacheJail.php
@@ -21,19 +21,15 @@ use OCP\Files\Search\ISearchOperator;
* Jail to a subdirectory of the wrapped cache
*/
class CacheJail extends CacheWrapper {
- /**
- * @var string
- */
- protected $root;
- protected $unjailedRoot;
+
+ protected string $unjailedRoot;
public function __construct(
?ICache $cache,
- string $root,
+ protected string $root,
?CacheDependencies $dependencies = null,
) {
parent::__construct($cache, $dependencies);
- $this->root = $root;
if ($cache instanceof CacheJail) {
$this->unjailedRoot = $cache->getSourcePath($root);
@@ -42,6 +38,9 @@ class CacheJail extends CacheWrapper {
}
}
+ /**
+ * @return string
+ */
protected function getRoot() {
return $this->root;
}
@@ -55,7 +54,10 @@ class CacheJail extends CacheWrapper {
return $this->unjailedRoot;
}
- protected function getSourcePath($path) {
+ /**
+ * @return string
+ */
+ protected function getSourcePath(string $path) {
if ($path === '') {
return $this->getRoot();
} else {
@@ -95,7 +97,7 @@ class CacheJail extends CacheWrapper {
/**
* get the stored metadata of a file or folder
*
- * @param string /int $file
+ * @param string|int $file
* @return ICacheEntry|false
*/
public function get($file) {
@@ -206,12 +208,12 @@ class CacheJail extends CacheWrapper {
/**
* update the folder size and the size of all parent folders
*
- * @param string|boolean $path
- * @param array $data (optional) meta data of the folder
+ * @param array|ICacheEntry|null $data (optional) meta data of the folder
*/
- public function correctFolderSize($path, $data = null, $isBackgroundScan = false) {
- if ($this->getCache() instanceof Cache) {
- $this->getCache()->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundScan);
+ public function correctFolderSize(string $path, $data = null, bool $isBackgroundScan = false): void {
+ $cache = $this->getCache();
+ if ($cache instanceof Cache) {
+ $cache->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundScan);
}
}
@@ -223,8 +225,9 @@ class CacheJail extends CacheWrapper {
* @return int|float
*/
public function calculateFolderSize($path, $entry = null) {
- if ($this->getCache() instanceof Cache) {
- return $this->getCache()->calculateFolderSize($this->getSourcePath($path), $entry);
+ $cache = $this->getCache();
+ if ($cache instanceof Cache) {
+ return $cache->calculateFolderSize($this->getSourcePath($path), $entry);
} else {
return 0;
}
diff --git a/lib/private/Files/Cache/Wrapper/CacheWrapper.php b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
index fdaa2cf4b7a..f2f1036d6a3 100644
--- a/lib/private/Files/Cache/Wrapper/CacheWrapper.php
+++ b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
@@ -221,12 +221,12 @@ class CacheWrapper extends Cache {
/**
* update the folder size and the size of all parent folders
*
- * @param string|boolean $path
- * @param array $data (optional) meta data of the folder
+ * @param array|ICacheEntry|null $data (optional) meta data of the folder
*/
- public function correctFolderSize($path, $data = null, $isBackgroundScan = false) {
- if ($this->getCache() instanceof Cache) {
- $this->getCache()->correctFolderSize($path, $data, $isBackgroundScan);
+ public function correctFolderSize(string $path, $data = null, bool $isBackgroundScan = false): void {
+ $cache = $this->getCache();
+ if ($cache instanceof Cache) {
+ $cache->correctFolderSize($path, $data, $isBackgroundScan);
}
}
@@ -238,8 +238,9 @@ class CacheWrapper extends Cache {
* @return int|float
*/
public function calculateFolderSize($path, $entry = null) {
- if ($this->getCache() instanceof Cache) {
- return $this->getCache()->calculateFolderSize($path, $entry);
+ $cache = $this->getCache();
+ if ($cache instanceof Cache) {
+ return $cache->calculateFolderSize($path, $entry);
} else {
return 0;
}