mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-31 11:53:48 -07:00
config: Hardened config logic against Time-Of-Check race conditions (#11368)
This commit is contained in:
@@ -873,11 +873,15 @@ CConfigManager::CConfigManager() {
|
||||
std::optional<std::string> CConfigManager::generateConfig(std::string configPath) {
|
||||
std::string parentPath = std::filesystem::path(configPath).parent_path();
|
||||
|
||||
if (!std::filesystem::is_directory(parentPath)) {
|
||||
Debug::log(WARN, "Creating config home directory");
|
||||
try {
|
||||
std::filesystem::create_directories(parentPath);
|
||||
} catch (std::exception& e) { throw e; }
|
||||
if (!parentPath.empty()) {
|
||||
std::error_code ec;
|
||||
bool created = std::filesystem::create_directories(parentPath, ec);
|
||||
if (ec) {
|
||||
Debug::log(ERR, "Couldn't create config home directory ({}): {}", ec.message(), parentPath);
|
||||
return "Config could not be generated.";
|
||||
}
|
||||
if (created)
|
||||
Debug::log(WARN, "Creating config home directory");
|
||||
}
|
||||
|
||||
Debug::log(WARN, "No config file found; attempting to generate.");
|
||||
@@ -886,7 +890,7 @@ std::optional<std::string> CConfigManager::generateConfig(std::string configPath
|
||||
ofs << AUTOGENERATED_PREFIX << EXAMPLE_CONFIG;
|
||||
ofs.close();
|
||||
|
||||
if (!std::filesystem::exists(configPath))
|
||||
if (ofs.fail())
|
||||
return "Config could not be generated.";
|
||||
|
||||
return configPath;
|
||||
@@ -3040,28 +3044,31 @@ std::optional<std::string> CConfigManager::handleSource(const std::string& comma
|
||||
std::string errorsFromParsing;
|
||||
|
||||
for (size_t i = 0; i < glob_buf->gl_pathc; i++) {
|
||||
auto value = absolutePath(glob_buf->gl_pathv[i], m_configCurrentPath);
|
||||
auto value = absolutePath(glob_buf->gl_pathv[i], m_configCurrentPath);
|
||||
|
||||
if (!std::filesystem::is_regular_file(value)) {
|
||||
if (std::filesystem::exists(value)) {
|
||||
Debug::log(WARN, "source= skipping non-file {}", value);
|
||||
continue;
|
||||
}
|
||||
std::error_code ec;
|
||||
auto file_status = std::filesystem::status(value, ec);
|
||||
|
||||
Debug::log(ERR, "source= file doesn't exist: {}", value);
|
||||
return "source= file " + value + " doesn't exist!";
|
||||
if (ec) {
|
||||
Debug::log(ERR, "source= file from glob result is inaccessible ({}): {}", ec.message(), value);
|
||||
return "source= file " + value + " is inaccessible!";
|
||||
}
|
||||
m_configPaths.emplace_back(value);
|
||||
|
||||
auto configCurrentPathBackup = m_configCurrentPath;
|
||||
m_configCurrentPath = value;
|
||||
|
||||
const auto THISRESULT = m_config->parseFile(value.c_str());
|
||||
|
||||
m_configCurrentPath = configCurrentPathBackup;
|
||||
|
||||
if (THISRESULT.error && errorsFromParsing.empty())
|
||||
errorsFromParsing += THISRESULT.getError();
|
||||
if (std::filesystem::is_regular_file(file_status)) {
|
||||
m_configPaths.emplace_back(value);
|
||||
auto configCurrentPathBackup = m_configCurrentPath;
|
||||
m_configCurrentPath = value;
|
||||
const auto THISRESULT = m_config->parseFile(value.c_str());
|
||||
m_configCurrentPath = configCurrentPathBackup;
|
||||
if (THISRESULT.error && errorsFromParsing.empty())
|
||||
errorsFromParsing += THISRESULT.getError();
|
||||
} else if (std::filesystem::is_directory(file_status)) {
|
||||
Debug::log(WARN, "source= skipping directory {}", value);
|
||||
continue;
|
||||
} else {
|
||||
Debug::log(WARN, "source= skipping non-regular-file {}", value);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (errorsFromParsing.empty())
|
||||
|
Reference in New Issue
Block a user