dont attempt to deserialize bracketed strings as arrays if they contain more brackets

This commit is contained in:
Robin Appelman 2026-01-03 16:05:51 +01:00
commit 842cf2407c
7 changed files with 22 additions and 4 deletions

View file

@ -16,7 +16,7 @@ well only the serde data model not every type might deserialize properly.
- Because the boolean values `0` and `1` can't be distinguished from numbers, it - Because the boolean values `0` and `1` can't be distinguished from numbers, it
is not possible to use booleans in untagged enums. is not possible to use booleans in untagged enums.
- When deserializing arrays by settings the same key multiple times, the keys - When deserializing arrays by setting the same key multiple times, the keys
have to be consecutive. have to be consecutive.
```vdf ```vdf

View file

@ -842,6 +842,18 @@ fn test_parse_entry() {
} }
pub(crate) fn string_is_array(string: &str) -> bool { pub(crate) fn string_is_array(string: &str) -> bool {
(string.starts_with('[') && string.ends_with(']')) if !((string.starts_with('[') && string.ends_with(']'))
|| (string.starts_with('{') && string.ends_with('}')) || (string.starts_with('{') && string.ends_with('}')))
{
return false;
}
let contents = &string[1..string.len() - 1];
// no nested arrays
if contents.contains(['{', '[']) {
return false;
}
true
} }

View file

@ -7,6 +7,8 @@
array 2 array 2
array "3" array "3"
windows_path "C:\test\no newline" windows_path "C:\test\no newline"
bracket_string "[{]"
ignored_bracket_string "[{]"
\\"$translucent" 1 // this is real vdf written by real valve developers \\"$translucent" 1 // this is real vdf written by real valve developers
"$envmaptint" .5 .5 .5 "$envmaptint" .5 .5 .5

View file

@ -43,6 +43,7 @@ enum Expected {
empty: (), empty: (),
array: Vec<u32>, array: Vec<u32>,
windows_path: String, windows_path: String,
bracket_string: String,
#[serde(rename = r#"\\"$translucent""#)] #[serde(rename = r#"\\"$translucent""#)]
translucent: bool, translucent: bool,
#[serde(rename = "$envmaptint")] #[serde(rename = "$envmaptint")]
@ -255,7 +256,6 @@ fn test_serde_table(path: &str) {
fn test_serde_from_table(path: &str) { fn test_serde_from_table(path: &str) {
let raw = read_to_string(path).unwrap(); let raw = read_to_string(path).unwrap();
let result = Table::load_from_str(&raw).unwrap(); let result = Table::load_from_str(&raw).unwrap();
dbg!(&result);
let material: Expected = from_entry(result.into()).expect("table to material"); let material: Expected = from_entry(result.into()).expect("table to material");
insta::assert_ron_snapshot!(format!("table_to_material__{}", path), material); insta::assert_ron_snapshot!(format!("table_to_material__{}", path), material);

View file

@ -15,8 +15,10 @@ expression: parsed
"2", "2",
"3", "3",
], ],
"bracket_string": "[{]",
"empty": "", "empty": "",
"empty quoted": "\"\"", "empty quoted": "\"\"",
"ignored_bracket_string": "[{]",
"windows_path": "C:\\test\\no newline", "windows_path": "C:\\test\\no newline",
}, },
} }

View file

@ -10,6 +10,7 @@ r#Resource/specificPanel.res(
3, 3,
], ],
windows_path: "C:\\test\\no newline", windows_path: "C:\\test\\no newline",
bracket_string: "[{]",
r#\\"$translucent": true, r#\\"$translucent": true,
r#$envmaptint: (0.5, 0.5, 0.5), r#$envmaptint: (0.5, 0.5, 0.5),
) )

View file

@ -10,6 +10,7 @@ r#Resource/specificPanel.res(
3, 3,
], ],
windows_path: "C:\\test\\no newline", windows_path: "C:\\test\\no newline",
bracket_string: "[{]",
r#\\"$translucent": true, r#\\"$translucent": true,
r#$envmaptint: (0.5, 0.5, 0.5), r#$envmaptint: (0.5, 0.5, 0.5),
) )