diff --git a/index.php b/index.php index 1b804488..a74849e2 100644 --- a/index.php +++ b/index.php @@ -89,9 +89,23 @@ public function __construct(string $baseDir) { if (!file_exists($configFileName)) { throw new \Exception('Could not find config.php. Is this file in the "updater" subfolder of Nextcloud?'); } + $filePointer = @fopen($configFileName, 'r'); + if ($filePointer === false) { + throw new \Exception('Could not open config.php.'); + } + if (!flock($filePointer, LOCK_SH)) { + throw new \Exception(sprintf('Could not acquire a shared lock on the config file')); + } + + try { + require_once $configFileName; + } finally { + // Close the file pointer and release the lock + flock($filePointer, LOCK_UN); + fclose($filePointer); + } /** @var array $CONFIG */ - require_once $configFileName; $this->configValues = $CONFIG; if (php_sapi_name() !== 'cli' && ($this->configValues['upgrade.disable-web'] ?? false)) { @@ -134,6 +148,38 @@ public function __construct(string $baseDir) { $this->buildTime = $buildTime; } + /** + * @return array{array, string} + */ + private function readConfigFile(): array { + if ($dir = getenv('NEXTCLOUD_CONFIG_DIR')) { + $configFileName = realpath($dir . '/config.php'); + } else { + $configFileName = $this->nextcloudDir . '/config/config.php'; + } + if (!file_exists($configFileName)) { + throw new \Exception('Could not find config.php (' . $configFileName . '). Is this file in the "updater" subfolder of Nextcloud?'); + } + $filePointer = @fopen($configFileName, 'r'); + if ($filePointer === false) { + throw new \Exception('Could not open config.php (' . $configFileName . ').'); + } + if (!flock($filePointer, LOCK_SH)) { + throw new \Exception('Could not acquire a shared lock on the config file (' . $configFileName . ')'); + } + + try { + require $configFileName; + } finally { + // Close the file pointer and release the lock + flock($filePointer, LOCK_UN); + fclose($filePointer); + } + + /** @var array $CONFIG */ + return [$CONFIG,$configFileName]; + } + /** * Returns whether the web updater is disabled * @@ -399,20 +445,14 @@ public function setMaintenanceMode(bool $state): void { } $this->silentLog('[info] configFileName ' . $configFileName); - // usually is already tested in the constructor but just to be on the safe side - if (!file_exists($configFileName)) { - throw new \Exception('Could not find config.php.'); - } - /** @var array $CONFIG */ - require $configFileName; $CONFIG['maintenance'] = $state; $content = "silentLog('[info] end of setMaintenanceMode()'); } diff --git a/lib/Updater.php b/lib/Updater.php index df188d7c..54891e40 100644 --- a/lib/Updater.php +++ b/lib/Updater.php @@ -51,9 +51,23 @@ public function __construct(string $baseDir) { if (!file_exists($configFileName)) { throw new \Exception('Could not find config.php. Is this file in the "updater" subfolder of Nextcloud?'); } + $filePointer = @fopen($configFileName, 'r'); + if ($filePointer === false) { + throw new \Exception('Could not open config.php.'); + } + if (!flock($filePointer, LOCK_SH)) { + throw new \Exception(sprintf('Could not acquire a shared lock on the config file')); + } + + try { + require_once $configFileName; + } finally { + // Close the file pointer and release the lock + flock($filePointer, LOCK_UN); + fclose($filePointer); + } /** @var array $CONFIG */ - require_once $configFileName; $this->configValues = $CONFIG; if (php_sapi_name() !== 'cli' && ($this->configValues['upgrade.disable-web'] ?? false)) { @@ -96,6 +110,38 @@ public function __construct(string $baseDir) { $this->buildTime = $buildTime; } + /** + * @return array{array, string} + */ + private function readConfigFile(): array { + if ($dir = getenv('NEXTCLOUD_CONFIG_DIR')) { + $configFileName = realpath($dir . '/config.php'); + } else { + $configFileName = $this->nextcloudDir . '/config/config.php'; + } + if (!file_exists($configFileName)) { + throw new \Exception('Could not find config.php (' . $configFileName . '). Is this file in the "updater" subfolder of Nextcloud?'); + } + $filePointer = @fopen($configFileName, 'r'); + if ($filePointer === false) { + throw new \Exception('Could not open config.php (' . $configFileName . ').'); + } + if (!flock($filePointer, LOCK_SH)) { + throw new \Exception('Could not acquire a shared lock on the config file (' . $configFileName . ')'); + } + + try { + require $configFileName; + } finally { + // Close the file pointer and release the lock + flock($filePointer, LOCK_UN); + fclose($filePointer); + } + + /** @var array $CONFIG */ + return [$CONFIG,$configFileName]; + } + /** * Returns whether the web updater is disabled * @@ -361,20 +407,14 @@ public function setMaintenanceMode(bool $state): void { } $this->silentLog('[info] configFileName ' . $configFileName); - // usually is already tested in the constructor but just to be on the safe side - if (!file_exists($configFileName)) { - throw new \Exception('Could not find config.php.'); - } - /** @var array $CONFIG */ - require $configFileName; $CONFIG['maintenance'] = $state; $content = "silentLog('[info] end of setMaintenanceMode()'); } diff --git a/tests/features/cli.feature b/tests/features/cli.feature index 4ef6754f..9a8bf3da 100644 --- a/tests/features/cli.feature +++ b/tests/features/cli.feature @@ -3,7 +3,7 @@ Feature: CLI updater Scenario: No update is available - 25.0.0 Given the current version is 25.0.0 When the CLI updater is run - Then the output should contain "Could not find config.php. Is this file in the "updater" subfolder of Nextcloud?" + Then the output should contain "Could not find config.php" Scenario: No update is available - 25.0.0 Given the current installed version is 25.0.0