mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-27 03:47:09 -06:00
Cap list label length when expanding level template text (#4003)
Fixes #3638 Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
66e5c06b25
commit
84c2d37a49
@@ -357,7 +357,8 @@ impl Counters {
|
||||
return Some((def.text.clone(), def));
|
||||
}
|
||||
let mut label = String::new();
|
||||
let mut chars = def.text.chars().peekable();
|
||||
// Word's level text is short; .docx and the lists command already cap it at 64.
|
||||
let mut chars = def.text.chars().take(MAX_LEVEL_TEXT).peekable();
|
||||
while let Some(c) = chars.next() {
|
||||
if c == '%'
|
||||
&& let Some(d) = chars.peek().and_then(|d| d.to_digit(10))
|
||||
@@ -375,6 +376,9 @@ impl Counters {
|
||||
f => f,
|
||||
};
|
||||
label.push_str(&fmt.format(val));
|
||||
if label.len() > MAX_LABEL_BYTES {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
label.push(c);
|
||||
}
|
||||
@@ -383,10 +387,29 @@ impl Counters {
|
||||
}
|
||||
}
|
||||
|
||||
/// Longest level text (in characters) expanded into a list label.
|
||||
const MAX_LEVEL_TEXT: usize = 64;
|
||||
/// Labels stop growing once they pass this many bytes.
|
||||
const MAX_LABEL_BYTES: usize = 256;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn a_huge_level_text_gives_a_bounded_label() {
|
||||
let mut n = Numbering::default();
|
||||
let id = n.add_list(ListKind::Numbered);
|
||||
let huge = Level { format: NumFormat::UpperRoman, text: "%1".repeat(30_000), start: u32::MAX, ..Level::default() };
|
||||
if let Some(num) = n.nums.iter_mut().find(|x| x.id == id) {
|
||||
num.level_overrides = vec![(0, huge)];
|
||||
}
|
||||
let mut c = Counters::default();
|
||||
let label = c.next_label(&n, id, 0).unwrap().0;
|
||||
assert!(label.len() <= 512, "label is {} bytes", label.len());
|
||||
assert!(label.starts_with("MMMM"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_list_s_own_level_definitions_win() {
|
||||
// A specification's article numbers: level 1 counts parts with no label of its own, level 2
|
||||
|
||||
Reference in New Issue
Block a user