From 0429a4e4296ef0a21804c546b7a3cf483e9c0a46 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 8 Jan 2023 02:04:25 +0100 Subject: [PATCH 1/4] Fix loading empty node.config.php --- src/Core/Config/Util/ConfigFileManager.php | 11 +++++++++-- .../Config/Cache/ConfigFileManagerTest.php | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Core/Config/Util/ConfigFileManager.php b/src/Core/Config/Util/ConfigFileManager.php index f3627cf47..fff240bb3 100644 --- a/src/Core/Config/Util/ConfigFileManager.php +++ b/src/Core/Config/Util/ConfigFileManager.php @@ -177,7 +177,7 @@ class ConfigFileManager { $filename = $this->configDir . '/' . self::CONFIG_DATA_FILE; - if (file_exists($filename)) { + if (file_exists($filename) && (filesize($filename) > 0)) { // The fallback empty return content $content = 'get('system', 'default_timezone')); } + + /** + * Test for empty node.config.php + */ + public function testEmptyFile() + { + $this->delConfigFile('node.config.php'); + + vfsStream::newFile('node.config.php') + ->at($this->root->getChild('config')) + ->setContent(''); + + $configFileManager = (new Config())->createConfigFileManager($this->root->url()); + $configCache = new Cache(); + + $configFileManager->setupCache($configCache); + + self::assertEquals(1,1); + } } From 2293ff6206b114be1bddbc789b843aa49b338ae7 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 8 Jan 2023 02:28:27 +0100 Subject: [PATCH 2/4] Add test for Addon failures --- src/Core/Config/Util/ConfigFileManager.php | 4 ++- src/Core/Config/ValueObject/Cache.php | 2 +- tests/src/Core/Config/Cache/CacheTest.php | 39 +++++++++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/Core/Config/Util/ConfigFileManager.php b/src/Core/Config/Util/ConfigFileManager.php index fff240bb3..011dbf0e4 100644 --- a/src/Core/Config/Util/ConfigFileManager.php +++ b/src/Core/Config/Util/ConfigFileManager.php @@ -194,11 +194,13 @@ class ConfigFileManager try { if (flock($configStream, LOCK_SH)) { + clearstatcache(true, $filename); + if (($filesize = filesize($filename)) === 0) { return; } - $content = fread($configStream, filesize($filename)); + $content = fread($configStream, $filesize); if (!$content) { throw new ConfigFileException(sprintf('Couldn\'t read file %s', $filename)); } diff --git a/src/Core/Config/ValueObject/Cache.php b/src/Core/Config/ValueObject/Cache.php index 208251164..7492d2873 100644 --- a/src/Core/Config/ValueObject/Cache.php +++ b/src/Core/Config/ValueObject/Cache.php @@ -283,7 +283,7 @@ class Cache $keys = array_keys($config[$category]); foreach ($keys as $key) { - if (!isset($this->config[$category][$key])) { + if (!key_exists($key, $this->config[$category] ?? [])) { $return[$category][$key] = $config[$category][$key]; } } diff --git a/tests/src/Core/Config/Cache/CacheTest.php b/tests/src/Core/Config/Cache/CacheTest.php index dc9b62dc0..e14b7998c 100644 --- a/tests/src/Core/Config/Cache/CacheTest.php +++ b/tests/src/Core/Config/Cache/CacheTest.php @@ -40,6 +40,7 @@ class CacheTest extends MockedTest 'int' => 235, 'dec' => 2.456, 'array' => ['1', 2, '3', true, false], + 'null' => null, ], 'config' => [ 'a' => 'value', @@ -503,6 +504,24 @@ class CacheTest extends MockedTest ], ], ], + /** @see https://github.com/friendica/friendica/issues/12486#issuecomment-1374609349 */ + 'test_with_null' => [ + 'data' => [ + 'test_with_null' => null, + 'config' => [ + 'register_policy' => 2, + 'register_text' => '', + 'sitename' => 'Friendica Social Network23', + 'hostname' => 'friendica.local', + 'private_addons' => false, + ], + 'system' => [ + 'dbclean_expire_conversation' => 90, + ], + ], + 'cat' => 'test_with_null', + 'assertion' => null, + ], ]; } @@ -511,10 +530,28 @@ class CacheTest extends MockedTest * * @dataProvider dataTestCat */ - public function testGetCategory(array $data, string $category, array $assertion) + public function testGetCategory($data, string $category, $assertion) { $cache = new Cache($data); self::assertEquals($assertion, $cache->get($category)); } + + /** + * Test that the cache can get merged with different categories + * + * @dataProvider dataTestCat + */ + public function testCatMerge($data, string $category) + { + $cache = new Cache($data); + + $newCache = $cache->merge(new Cache([ + $category => [ + 'new_key' => 'new_value', + ], + ])); + + self::assertEquals('new_value', $newCache->get($category, 'new_key')); + } } From 5ea50a9e81a7f363040d7c86a4a41b8a1f8f7758 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 8 Jan 2023 02:28:47 +0100 Subject: [PATCH 3/4] Fix "null" addon list --- src/Core/Config/ValueObject/Cache.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Core/Config/ValueObject/Cache.php b/src/Core/Config/ValueObject/Cache.php index 7492d2873..61a65c3e7 100644 --- a/src/Core/Config/ValueObject/Cache.php +++ b/src/Core/Config/ValueObject/Cache.php @@ -311,6 +311,11 @@ class Cache if (is_array($cache->config[$category])) { $keys = array_keys($cache->config[$category]); + if (is_null($newConfig[$category] ?? null)) { + $newConfig[$category] = []; + $newSource[$category] = []; + } + foreach ($keys as $key) { $newConfig[$category][$key] = $cache->config[$category][$key]; $newSource[$category][$key] = $cache->source[$category][$key]; From 979672a3c1c6aacb91f005e5912763ad55d08dd1 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 8 Jan 2023 02:33:50 +0100 Subject: [PATCH 4/4] Filter disabled addons with "null" --- src/Core/Addon.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Core/Addon.php b/src/Core/Addon.php index 8d1a86691..06f6a1296 100644 --- a/src/Core/Addon.php +++ b/src/Core/Addon.php @@ -84,7 +84,7 @@ class Addon public static function getAdminList(): array { $addons_admin = []; - $addons = DI::config()->get('addons') ?? []; + $addons = array_filter(DI::config()->get('addons') ?? []); ksort($addons); foreach ($addons as $name => $data) { @@ -117,7 +117,7 @@ class Addon */ public static function loadAddons() { - self::$addons = array_keys(DI::config()->get('addons') ?? []); + self::$addons = array_keys(array_filter(DI::config()->get('addons') ?? [])); } /** @@ -192,7 +192,7 @@ class Addon */ public static function reload() { - $addons = DI::config()->get('addons') ?? []; + $addons = array_filter(DI::config()->get('addons') ?? []); foreach ($addons as $name => $data) { $addonname = Strings::sanitizeFilePathItem(trim($name)); @@ -315,7 +315,7 @@ class Addon public static function getVisibleList(): array { $visible_addons = []; - $addons = DI::config()->get('addons') ?? []; + $addons = array_filter(DI::config()->get('addons') ?? []); foreach ($addons as $name => $data) { $visible_addons[] = $name;