diff --git a/crates/color/src/ase.rs b/crates/color/src/ase.rs index c20c249e..6cfd7203 100644 --- a/crates/color/src/ase.rs +++ b/crates/color/src/ase.rs @@ -98,9 +98,11 @@ pub fn read(bytes: &[u8]) -> Result, AseError> { } } let color = match &model[..] { - b"CMYK" => Color::Cmyk { c: b.f32()?, m: b.f32()?, y: b.f32()?, k: b.f32()? }, - b"RGB " => Color::Rgb { r: b.f32()?, g: b.f32()?, b: b.f32()? }, - b"Gray" => Color::Gray { k: 1.0 - b.f32()? }, + b"CMYK" => { + Color::Cmyk { c: b.f32()?.clamp(0.0, 1.0), m: b.f32()?.clamp(0.0, 1.0), y: b.f32()?.clamp(0.0, 1.0), k: b.f32()?.clamp(0.0, 1.0) } + } + b"RGB " => Color::Rgb { r: b.f32()?.clamp(0.0, 1.0), g: b.f32()?.clamp(0.0, 1.0), b: b.f32()?.clamp(0.0, 1.0) }, + b"Gray" => Color::Gray { k: (1.0 - b.f32()?).clamp(0.0, 1.0) }, b"LAB " => { let (l, a, bb) = (b.f32()?, b.f32()?, b.f32()?); let [r, g, bl] = cms::lab::lab_to_srgb(cms::Lab { l: l * 100.0, a, b: bb }); @@ -231,6 +233,36 @@ mod tests { assert_eq!(read(&write(&sw[1..])).map(|w| w.len()), Ok(MAX_COLORS), "up to the limit"); } + #[test] + fn out_of_range_components_are_clamped() { + let mut f = Vec::new(); + f.extend(b"ASEF\x00\x01\x00\x00"); + f.extend(3u32.to_be_bytes()); + let cases: [(&[u8; 4], &[f32]); 3] = [(b"RGB ", &[5.0, -2.0, 0.5]), (b"CMYK", &[2.0, -1.0, 0.5, 9.0]), (b"Gray", &[-1.0])]; + for (model, vals) in cases { + let mut c = Vec::new(); + c.extend(2u16.to_be_bytes()); + c.extend([0, b'X', 0, 0]); + c.extend(model); + for v in vals { + c.extend(v.to_bits().to_be_bytes()); + } + c.extend(2u16.to_be_bytes()); + f.extend(COLOR.to_be_bytes()); + f.extend((c.len() as u32).to_be_bytes()); + f.extend(&c); + } + let colors: Vec = read(&f) + .unwrap() + .into_iter() + .filter_map(|s| match s.value { + SwatchValue::Color { color, .. } => Some(color), + _ => None, + }) + .collect(); + assert_eq!(colors, [Color::Rgb { r: 1.0, g: 0.0, b: 0.5 }, Color::Cmyk { c: 1.0, m: 0.0, y: 0.5, k: 1.0 }, Color::Gray { k: 1.0 },]); + } + #[test] fn non_finite_components_are_skipped() { let sw = |name: &str, color: Color| Swatch {