mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-24 02:06:54 -06:00
Truncate ASE swatch names that overflow the u16 length field
Found while testing crates/color/src/ase.rs:131-132 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
443ea4640c
commit
352abea9fc
+23
-2
@@ -128,8 +128,14 @@ pub fn write(swatches: &[Swatch]) -> Vec<u8> {
|
||||
continue;
|
||||
}
|
||||
let mut b = Vec::new();
|
||||
let units: Vec<u16> = s.name.encode_utf16().chain(std::iter::once(0)).collect();
|
||||
b.extend((units.len() as u16).to_be_bytes());
|
||||
// The length field is a u16 that counts the terminating NUL: truncate longer names.
|
||||
let mut units: Vec<u16> = s.name.encode_utf16().take(usize::from(u16::MAX) - 1).collect();
|
||||
// Do not leave half of a surrogate pair at the cut.
|
||||
if units.last().is_some_and(|u| (0xD800..0xDC00).contains(u)) {
|
||||
units.pop();
|
||||
}
|
||||
units.push(0);
|
||||
b.extend(u16::try_from(units.len()).unwrap_or(u16::MAX).to_be_bytes());
|
||||
for u in units {
|
||||
b.extend(u.to_be_bytes());
|
||||
}
|
||||
@@ -233,6 +239,21 @@ mod tests {
|
||||
assert_eq!(read(&write(&sw[1..])).map(|w| w.len()), Ok(MAX_COLORS), "up to the limit");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn over_long_name_is_truncated_to_fit() {
|
||||
let sw = vec![Swatch {
|
||||
name: "x".repeat(70_000),
|
||||
value: SwatchValue::Color { color: Color::Gray { k: 0.5 }, color_type: ColorType::Process },
|
||||
locked: false,
|
||||
named: true,
|
||||
hidden: false,
|
||||
}];
|
||||
let back = read(&write(&sw)).unwrap();
|
||||
assert_eq!(back.len(), 1, "the swatch must survive the round trip");
|
||||
assert_eq!(back[0].name, "x".repeat(usize::from(u16::MAX) - 1));
|
||||
assert_eq!(back[0].value, sw[0].value);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn out_of_range_components_are_clamped() {
|
||||
let mut f = Vec::new();
|
||||
|
||||
Reference in New Issue
Block a user