diff --git a/php/src/Data/ConfigurationManager.php b/php/src/Data/ConfigurationManager.php index cd29c205..029a377f 100644 --- a/php/src/Data/ConfigurationManager.php +++ b/php/src/Data/ConfigurationManager.php @@ -302,6 +302,9 @@ class ConfigurationManager if ($this->config === [] && file_exists(DataConst::GetConfigFile())) { $configContent = (string)file_get_contents(DataConst::GetConfigFile()); + if ($configContent === '') { + throw new \RuntimeException("The config file " . DataConst::GetConfigFile() . " is empty. It may have been truncated due to low disk space. Please restore it from a backup."); + } $this->config = json_decode($configContent, true, 512, JSON_THROW_ON_ERROR); } @@ -702,7 +705,21 @@ class ConfigurationManager if ($df !== false && (int)$df < $size) { throw new InvalidSettingConfigurationException(DataConst::GetDataDirectory() . " does not have enough space for writing the config file! Not writing it back!"); } - file_put_contents(DataConst::GetConfigFile(), $content); + // Write to a temp file first to avoid truncating the config file if the + // disk fills up mid-write. rename() is atomic on POSIX filesystems, so the + // original config is never touched until the new content is fully on disk. + $tempFile = DataConst::GetConfigFile() . '.tmp'; + if (file_put_contents($tempFile, $content) === false) { + // The file probably wasn't created, but better check nonetheless. + if (file_exists($tempFile)) { + unlink($tempFile); + } + throw new InvalidSettingConfigurationException("Failed to write temporary config file: " . $tempFile); + } + if (!rename($tempFile, DataConst::GetConfigFile())) { + unlink($tempFile); + throw new InvalidSettingConfigurationException("Failed to rename " . $tempFile . " to " . DataConst::GetConfigFile()); + } $this->config = []; }