From 40c6de8e318d9f4dde148ec18f8ebc0512eae3bc Mon Sep 17 00:00:00 2001 From: Mg Pig Date: Sun, 19 Apr 2026 10:39:04 +0800 Subject: [PATCH] fix(core): restrict implicit config merge to explicit config files (#2127) --- easytier/src/core.rs | 48 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/easytier/src/core.rs b/easytier/src/core.rs index 634f36bb..f57daf14 100644 --- a/easytier/src/core.rs +++ b/easytier/src/core.rs @@ -788,20 +788,33 @@ impl Cli { } impl NetworkOptions { - fn can_merge(&self, cfg: &TomlConfigLoader, config_file_count: usize) -> bool { + fn can_merge( + &self, + cfg: &TomlConfigLoader, + source: ConfigSource, + explicit_config_file_count: usize, + config_dir_file_count: usize, + ) -> bool { if (*self) == NetworkOptions::default() { return false; } - if config_file_count == 1 { + + if source == ConfigSource::CliConfigFile + && explicit_config_file_count == 1 + && config_dir_file_count == 0 + { return true; } + let Some(network_name) = &self.network_name else { return false; }; - if cfg.get_network_identity().network_name == *network_name { - return true; + + if source == ConfigSource::ConfigDir { + return cfg.get_network_identity().network_name == *network_name; } - false + + cfg.get_network_identity().network_name == *network_name } fn merge_into(&self, cfg: &TomlConfigLoader) -> anyhow::Result<()> { @@ -1122,6 +1135,12 @@ impl NetworkOptions { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum ConfigSource { + CliConfigFile, + ConfigDir, +} + impl LoggingConfigLoader for &LoggingOptions { fn get_console_logger_config(&self) -> ConsoleLoggerConfig { ConsoleLoggerConfig { @@ -1304,8 +1323,13 @@ async fn run_main(cli: Cli) -> anyhow::Result<()> { None }; + let explicit_config_file_count = cli.config_file.as_ref().map_or(0, |files| files.len()); + let mut config_dir_file_count = 0; let mut config_files = if let Some(v) = cli.config_file { - v.clone() + v.iter() + .cloned() + .map(|path| (path, ConfigSource::CliConfigFile)) + .collect() } else { vec![] }; @@ -1326,7 +1350,8 @@ async fn run_main(cli: Cli) -> anyhow::Result<()> { if ext != "toml" { continue; } - config_files.push(path); + config_dir_file_count += 1; + config_files.push((path, ConfigSource::ConfigDir)); } } let config_file_count = config_files.len(); @@ -1339,7 +1364,7 @@ async fn run_main(cli: Cli) -> anyhow::Result<()> { cli.network_options.network_name.is_some() } }; - for config_file in config_files { + for (config_file, source) in config_files { let (cfg, mut control) = load_config_from_file( &config_file, cli.config_dir.as_ref(), @@ -1347,7 +1372,12 @@ async fn run_main(cli: Cli) -> anyhow::Result<()> { ) .await?; - if cli.network_options.can_merge(&cfg, config_file_count) { + if cli.network_options.can_merge( + &cfg, + source, + explicit_config_file_count, + config_dir_file_count, + ) { cli.network_options .merge_into(&cfg) .with_context(|| format!("failed to merge config from cli: {:?}", config_file))?;