diff options
Diffstat (limited to 'lib/private/Config.php')
-rw-r--r-- | lib/private/Config.php | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/lib/private/Config.php b/lib/private/Config.php index ee30b8efc5e..a9eb58a1866 100644 --- a/lib/private/Config.php +++ b/lib/private/Config.php @@ -35,7 +35,7 @@ class Config { */ public function __construct($configDir, $fileName = 'config.php') { $this->configDir = $configDir; - $this->configFilePath = $this->configDir.$fileName; + $this->configFilePath = $this->configDir . $fileName; $this->configFileName = $fileName; $this->readData(); $this->isReadOnly = $this->getValue('config_is_read_only', false); @@ -49,7 +49,7 @@ class Config { * @return array an array of key names */ public function getKeys() { - return array_keys($this->cache); + return array_merge(array_keys($this->cache), array_keys($this->envCache)); } /** @@ -64,19 +64,38 @@ class Config { * @return mixed the value or $default */ public function getValue($key, $default = null) { - $envKey = self::ENV_PREFIX . $key; - if (isset($this->envCache[$envKey])) { - return $this->envCache[$envKey]; + if (isset($this->envCache[$key])) { + return self::trustSystemConfig($this->envCache[$key]); } if (isset($this->cache[$key])) { - return $this->cache[$key]; + return self::trustSystemConfig($this->cache[$key]); } return $default; } /** + * Since system config is admin controlled, we can tell psalm to ignore any taint + * + * @psalm-taint-escape callable + * @psalm-taint-escape cookie + * @psalm-taint-escape file + * @psalm-taint-escape has_quotes + * @psalm-taint-escape header + * @psalm-taint-escape html + * @psalm-taint-escape include + * @psalm-taint-escape ldap + * @psalm-taint-escape shell + * @psalm-taint-escape sql + * @psalm-taint-escape unserialize + * @psalm-pure + */ + public static function trustSystemConfig(mixed $value): mixed { + return $value; + } + + /** * Sets and deletes values and writes the config.php * * @param array $configs Associative array with `key => value` pairs @@ -172,7 +191,7 @@ class Config { $configFiles = [$this->configFilePath]; // Add all files in the config dir ending with the same file name - $extra = glob($this->configDir.'*.'.$this->configFileName); + $extra = glob($this->configDir . '*.' . $this->configFileName); if (is_array($extra)) { natsort($extra); $configFiles = array_merge($configFiles, $extra); @@ -184,10 +203,11 @@ class Config { // Invalidate opcache (only if the timestamp changed) if (function_exists('opcache_invalidate')) { - opcache_invalidate($file, false); + @opcache_invalidate($file, false); } - $filePointer = @fopen($file, 'r'); + // suppressor doesn't work here at boot time since it'll go via our onError custom error handler + $filePointer = file_exists($file) ? @fopen($file, 'r') : false; if ($filePointer === false) { // e.g. wrong permissions are set if ($file === $this->configFilePath) { @@ -226,7 +246,16 @@ class Config { } } - $this->envCache = getenv(); + // grab any "NC_" environment variables + $envRaw = getenv(); + // only save environment variables prefixed with "NC_" in the cache + $envPrefixLen = strlen(self::ENV_PREFIX); + foreach ($envRaw as $rawEnvKey => $rawEnvValue) { + if (str_starts_with($rawEnvKey, self::ENV_PREFIX)) { + $realKey = substr($rawEnvKey, $envPrefixLen); + $this->envCache[$realKey] = $rawEnvValue; + } + } } /** @@ -237,17 +266,17 @@ class Config { * @throws HintException If the config file cannot be written to * @throws \Exception If no file lock can be acquired */ - private function writeData() { + private function writeData(): void { $this->checkReadOnly(); - if (!is_file(\OC::$configDir.'/CAN_INSTALL') && !isset($this->cache['version'])) { + if (!is_file(\OC::$configDir . '/CAN_INSTALL') && !isset($this->cache['version'])) { throw new HintException(sprintf('Configuration was not read or initialized correctly, not overwriting %s', $this->configFilePath)); } // Create a php file ... $content = "<?php\n"; $content .= '$CONFIG = '; - $content .= var_export($this->cache, true); + $content .= var_export(self::trustSystemConfig($this->cache), true); $content .= ";\n"; touch($this->configFilePath); @@ -268,7 +297,7 @@ class Config { $df = disk_free_space($this->configDir); $size = strlen($content) + 10240; if ($df !== false && $df < (float)$size) { - throw new \Exception($this->configDir . " does not have enough space for writing the config file! Not writing it back!"); + throw new \Exception($this->configDir . ' does not have enough space for writing the config file! Not writing it back!'); } } |