Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: detect inadvertent overlapping config files that break things #49956

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions lib/private/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,31 +197,42 @@ private function readData() {
}

http_response_code(500);
die(sprintf('FATAL: Could not open the config file %s', $file));
die(sprintf('FATAL: Could not open the config file: %s' . PHP_EOL, basename($file)));
}

// Try to acquire a file lock
if (!flock($filePointer, LOCK_SH)) {
throw new \Exception(sprintf('Could not acquire a shared lock on the config file %s', $file));
http_response_code(500);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Http framework:

public const STATUS_INTERNAL_SERVER_ERROR = 500;

die(sprintf('FATAL: Could not acquire a shared lock on the config file: %s' . PHP_EOL, basename($file)));
}

try {
// wrap with output buffer to catch some problems and avoid generating uncontrolled output
ob_start();
include $file;
$ob_length = ob_get_length();
ob_end_clean();
// syntax issues in the config file like leading spaces cause PHP to send output
if ($ob_length > 0 && !defined('PHPUNIT_RUN')) { // indicator of leading content discovered
$errorMessage = sprintf('FATAL: Config file has leading content, please remove everything before "<?php" in: %s' . PHP_EOL, basename($file));
if (!defined('OC_CONSOLE')) {
die(\OCP\Util::sanitizeHTML($errorMessage));
} else {
die($errorMessage);
}
}
} finally {
// Close the file pointer and release the lock
flock($filePointer, LOCK_UN);
fclose($filePointer);
}

if (!defined('PHPUNIT_RUN') && headers_sent()) {
// syntax issues in the config file like leading spaces causing PHP to send output
$errorMessage = sprintf('Config file has leading content, please remove everything before "<?php" in %s', basename($file));
if (!defined('OC_CONSOLE')) {
print(\OCP\Util::sanitizeHTML($errorMessage));
}
throw new \Exception($errorMessage);
}
if (isset($CONFIG) && is_array($CONFIG)) {
// try to detect unintentionally overlapping config files (which will break things like upgrades)
if (isset($CONFIG['version']) && $file !== $this->configFilePath) {
http_response_code(500);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

die(sprintf('FATAL: Conflicting version value in the loaded config file: %s' . PHP_EOL, basename($file)));
}
$this->cache = array_merge($this->cache, $CONFIG);
}
}
Expand Down
Loading