Merge pull request #1301 from Silvertree2010/fix/h368-ase-swatch-import-stores-out-of

Clamp RGB, CMYK and Gray components on ASE import
This commit is contained in:
Brandon Thomas
2026-10-19 02:48:51 -04:00
committed by GitHub
+35 -3
View File
@@ -98,9 +98,11 @@ pub fn read(bytes: &[u8]) -> Result<Vec<Swatch>, 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<Color> = 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 {