Audit: Targa and palette encoders check pixel buffer sizes

This commit is contained in:
Dylan M. Taylor
2026-10-24 04:49:07 +07:00
committed by bflatastic
parent 9843d5f1ab
commit 52ceefe906
2 changed files with 4 additions and 3 deletions
+2 -1
View File
@@ -197,7 +197,8 @@ pub fn quantize_locked(rgba: &[u8], width: u32, height: u32, o: &PaletteOptions,
}
let weights = o.reduction.weights();
let dither = if exact { Dither::None } else { o.dither };
let mut indices = map(&colors, width as usize, &palette, weights, dither, f32::from(o.dither_amount.min(100)) / 100.0, |i| clear(&px[i]));
// (A width past the pixels there are would size the error rows from a number nothing checked.)
let mut indices = map(&colors, (width as usize).min(colors.len()), &palette, weights, dither, f32::from(o.dither_amount.min(100)) / 100.0, |i| clear(&px[i]));
// Drop the entries no pixel uses (fixed palettes), keeping the order.
let mut used = [false; 256];
for (i, &ix) in indices.iter().enumerate() {
+2 -2
View File
@@ -34,11 +34,11 @@ pub fn encode(rgba: &[u8], width: u32, height: u32, o: &TgaOptions) -> Result<Ve
return Err(format!("{width} × {height} pixels is too large for Targa (at most 65535 pixels a side): lower the resolution"));
};
let (w, h) = (usize::from(w16), usize::from(h16));
if w == 0 || h == 0 || w * h * 4 != rgba.len() {
if w == 0 || h == 0 || (w * h).checked_mul(4) != Some(rgba.len()) {
return Err("Targa encoding failed: the pixel buffer doesn't match the image size".into());
}
let px = rgba.as_chunks::<4>().0;
let mut out = Vec::with_capacity(18 + w * h * usize::from(o.depth / 8) + 26);
let mut out = Vec::with_capacity((w * h).saturating_mul(usize::from(o.depth / 8)).saturating_add(18 + 26));
// No image id or colour map, uncompressed true colour, origin (0, 0).
out.extend([0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
out.extend(w16.to_le_bytes());