From cb2646c7b4974e33f4148752deec71f0d589b0f3 Mon Sep 17 00:00:00 2001 From: Fiona Ebner Date: Wed, 30 Nov 2022 14:12:30 +0100 Subject: [PATCH] section config: fix handling array schema in unknown sections Mostly relevant when the config is written out again after parsing it with unknown sections. Previously, with duplicate keys, only the last value would be saved. Now, duplicate keys are assumed to be part of an array schema and handled as such. Because the unknown section parsing does not know if a certain property does actually have an array schema, it's not possible to detect duplicate keys for non-array-schema properties, and if a property with array-schema shows up only once, it will not be saved as a Value::Array, but a Value::String. Writing, or to be precise the format_section_content methods, already handle Value::Array, so don't need to be adapted. Fixes: 0cd0d16 ("section config: support allowing unknown section types") Signed-off-by: Fiona Ebner --- proxmox-section-config/src/lib.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/proxmox-section-config/src/lib.rs b/proxmox-section-config/src/lib.rs index 43f62854..3c09b5d4 100644 --- a/proxmox-section-config/src/lib.rs +++ b/proxmox-section-config/src/lib.rs @@ -529,7 +529,14 @@ impl SectionConfig { continue; } if let Some((key, value)) = (self.parse_section_content)(line) { - config[key] = json!(value); + match &mut config[&key] { + Value::Null => config[key] = json!(value), + // Assume it's an array schema in order to handle actual array + // schemas as good as we can. + Value::String(current) => config[key] = json!([current, value]), + Value::Array(array) => array.push(json!(value)), + other => bail!("got unexpected Value {:?}", other), + } } else { bail!("syntax error (expected section properties)"); } @@ -1137,6 +1144,8 @@ fn test_section_config_array() { let mut config = SectionConfig::new(&ID_SCHEMA); config.register_plugin(plugin); + let config_unknown = SectionConfig::new(&ID_SCHEMA).allow_unknown_sections(true); + let raw = r" sync: s-4a1011e8-40e2 @@ -1182,6 +1191,15 @@ sync: s-6c32330a-6204 check(res); + let res_unknown = config_unknown.parse(filename, raw).unwrap(); + println!("RES (unknown): {:?}", res_unknown); + let written_unknown = config_unknown.write(filename, &res_unknown).unwrap(); + println!("CONFIG (unknown):\n{}", written_unknown); + + check(res_unknown); + + assert_eq!(written, written_unknown); + let raw = r" sync: fail