mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Improve handling of invalid placeholders during message substitution
This commit is contained in:
+80
-4
@@ -327,8 +327,17 @@ fn format(text: &str, subs: &[&str]) -> Result<Box<str>, MetadataParsingErrorRea
|
||||
|
||||
for slice in text.split_inclusive(['{', '}']) {
|
||||
if let Some(prefix) = slice.strip_suffix('{') {
|
||||
new_text.push_str(prefix);
|
||||
maybe_in_placeholder = true;
|
||||
if maybe_in_placeholder {
|
||||
if prefix.is_empty() {
|
||||
new_text.push_str(slice);
|
||||
} else {
|
||||
new_text.push('{');
|
||||
new_text.push_str(prefix);
|
||||
}
|
||||
} else {
|
||||
new_text.push_str(prefix);
|
||||
maybe_in_placeholder = true;
|
||||
}
|
||||
} else if let Some(prefix) = slice.strip_suffix('}') {
|
||||
if maybe_in_placeholder {
|
||||
if let Ok(sub_index) = prefix.parse::<usize>() {
|
||||
@@ -343,18 +352,27 @@ fn format(text: &str, subs: &[&str]) -> Result<Box<str>, MetadataParsingErrorRea
|
||||
unused_sub_indexes.remove(&sub_index);
|
||||
} else {
|
||||
// Not a valid placeholder, treat it as normal text.
|
||||
new_text.push_str(prefix);
|
||||
new_text.push('{');
|
||||
new_text.push_str(slice);
|
||||
}
|
||||
|
||||
maybe_in_placeholder = false;
|
||||
} else {
|
||||
new_text.push_str(prefix);
|
||||
new_text.push_str(slice);
|
||||
}
|
||||
} else {
|
||||
if maybe_in_placeholder {
|
||||
new_text.push('{');
|
||||
maybe_in_placeholder = false;
|
||||
}
|
||||
new_text.push_str(slice);
|
||||
}
|
||||
}
|
||||
|
||||
if maybe_in_placeholder {
|
||||
new_text.push('{');
|
||||
}
|
||||
|
||||
if let Some(sub_index) = unused_sub_indexes.first() {
|
||||
if let Some(sub) = subs.get(*sub_index) {
|
||||
return Err(MetadataParsingErrorReason::MissingPlaceholder(
|
||||
@@ -742,6 +760,64 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
mod format {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn should_treat_invalid_placeholders_as_literals() {
|
||||
let format_no_subs = |i| format(i, &[]).unwrap();
|
||||
|
||||
let input = "a{";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a{a";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a{}";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a{a}";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a}";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a{ }";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a{0a}";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a{{";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a{b{";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a{b{c";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a}}b";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a}b}";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
let input = "a}b}c";
|
||||
assert_eq!(input, format_no_subs(input).as_ref());
|
||||
|
||||
assert_eq!("a{b", format("a{{0}", &["b"]).unwrap().as_ref());
|
||||
|
||||
assert_eq!("ab}", format("a{0}}", &["b"]).unwrap().as_ref());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allows_leading_zeroes_in_placeholders() {
|
||||
let input = "a{0}-{01}";
|
||||
assert_eq!("ab-c", format(input, &["b", "c"]).unwrap().as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
mod emit_yaml {
|
||||
use super::*;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user