taler-rust

GNU Taler code in Rust. Largely core banking integrations.
Log | Files | Refs | Submodules | README | LICENSE

commit 3ddbe6d4f37eecf02a242c543f25b6b0de2703bf
parent 7bf1b433bddec555748a8fd516704dbee1d5318b
Author: Antoine A <>
Date:   Wed, 12 Feb 2025 17:17:44 +0100

common: fix config inline secret recursion

Diffstat:
Mcommon/taler-common/src/config.rs | 36++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/common/taler-common/src/config.rs b/common/taler-common/src/config.rs @@ -234,7 +234,7 @@ pub mod parser { } } "inline-secret" => { - let (section, file) = arg.split_once(" ").ok_or_else(|| + let (section, secret_file) = arg.split_once(" ").ok_or_else(|| line_err( "Invalid configuration, @inline-secret@ directive requires exactly two arguments", src, @@ -243,24 +243,23 @@ pub mod parser { )?; let section = section.to_uppercase(); + let mut secret_cfg = Parser::empty(); - let mut tmp = Parser::empty(); - tmp.parse_file(src, depth)?; - - if let Err(e) = tmp.parse_file(src, depth) { + if let Err(e) = secret_cfg.parse_file(secret_file.as_ref(), depth) { if let ParserErr::IO(_, path, err) = e { warn!(target: "config", "{}", io_err("read secrets", path, err)) } else { return Err(e); } - } else if let Some(secret_section) = tmp.sections.swap_remove(&section) + } else if let Some(secret_section) = + secret_cfg.sections.swap_remove(&section) { self.sections .entry(section) .or_default() .extend(secret_section); } else { - warn!(target: "config", "{}", line_err(format!("Configuration file at '{}' loaded with @inline-secret@ does not contain section '{section}' ", file), src, num)); + warn!(target: "config", "{}", line_err(format!("Configuration file at '{}' loaded with @inline-secret@ does not contain section '{section}' ", secret_file), src, num)); } } unknown => { @@ -837,9 +836,10 @@ mod test { let config_path_fmt = config_path.to_string_lossy(); let second_path_fmt = second_path.to_string_lossy(); - let check = |err: String| check_err(err, Config::from_file(SOURCE, Some(&config_path))); + let check_err = |err: String| check_err(err, Config::from_file(SOURCE, Some(&config_path))); + let check_ok = || Config::from_file(SOURCE, Some(&config_path)).unwrap(); - check(format!( + check_err(format!( "Could not read config at '{config_path_fmt}': entity not found" )); @@ -851,15 +851,16 @@ mod test { error!("Cannot finish this test if root"); return; } - check(format!( + check_err(format!( "Could not read config at '{config_path_fmt}': permission denied" )); config_file .set_permissions(Permissions::from_mode(0o666)) .unwrap(); + check_ok(); std::fs::write(&config_path, "@inline@ test-second-conf.conf").unwrap(); - check(format!( + check_err(format!( "Could not read config at '{second_path_fmt}': entity not found" )); @@ -867,28 +868,31 @@ mod test { second_file .set_permissions(Permissions::from_mode(0222)) .unwrap(); - check(format!( + check_err(format!( "Could not read config at '{second_path_fmt}': permission denied" )); std::fs::write(&config_path, "@inline-matching@[*").unwrap(); - check(format!( + check_err(format!( "Malformed glob regex at '{config_path_fmt}:1': Pattern syntax error near position 16: invalid range pattern" )); std::fs::write(&config_path, "@inline-matching@*second-conf.conf").unwrap(); - check(format!( + check_err(format!( "Could not read config at '{second_path_fmt}': permission denied" )); std::fs::write(&config_path, "\n@inline-matching@*.conf").unwrap(); - check(format!( + check_err(format!( "Recursion limit in config inlining at '{config_path_fmt}:2'" )); std::fs::write(&config_path, "\n\n@inline-matching@ *.conf").unwrap(); - check(format!( + check_err(format!( "Recursion limit in config inlining at '{config_path_fmt}:3'" )); + + std::fs::write(&config_path, "@inline-secret@ secret test-second-conf.conf").unwrap(); + check_ok(); } #[test]