chinedufn / psd

A Rust API for parsing and working with PSD files.
https://chinedufn.github.io/psd
Apache License 2.0
265 stars 40 forks source link

Error: Index out of bounds #26

Open gregl83 opened 2 years ago

gregl83 commented 2 years ago

Hi!

Encountering a bug when attempting to load the pixels of each layer in a PSD.

Snippet

let file = fs::File::open(psd_path).expect("file should open read only");

let mut reader = BufReader::new(file);
let mut buffer = Vec::new();

reader.read_to_end(&mut buffer).unwrap();

let psd = Psd::from_bytes(buffer.as_slice()).unwrap();

for layer in psd.layers().iter() {
    let name = layer.name();

    let skip_file = Regex::new(r"^_.*").unwrap();
    if !skip_file.is_match(name) {
        println!("{:?}", name);

        let pixels: Vec<u8> = layer.rgba();
    }
}

Error

thread 'main' panicked at 'index out of bounds: the len is 16384 but the index is 16472', /home/gregl83/.cargo/registry/src/github.com-1ecc6299db9ec823/psd-0.2.0/src/psd_channel.rs:126:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Untested Presumption Layer size can be larger than a PSD project size (dimensions) resulting in overflowed pixels in the PSD overflowing the rgba pixel vector.

chinedufn commented 2 years ago

Thanks for reporting this issue!


So it looks like right now when generating the RGBA bytes vector we always use the psd's width and height https://github.com/chinedufn/psd/blob/930d00117fa9d625ebb1f006066437ec3156d2f2/src/psd_channel.rs#L33


Here's a rough guide on how to fix this:

  1. Add a test to https://github.com/chinedufn/psd/blob/930d00117fa9d625ebb1f006066437ec3156d2f2/tests/layer_and_mask_information_section.rs#L18 .. perhaps called layer_larger_than_psd, where we try to get the .rgba() of a 2x2 layer that is inside of a 1x1 PSD file. Would want to add this new test PSD file to the test fixtures directory https://github.com/chinedufn/psd/tree/c434d36b4e1d00a0ca14e9b39d6e7fcbdd6127ff/tests/fixtures . Test should fail.

  2. Rename the psd_width and psd_height methods to pixel_width and pixel_height

  3. Replace self.layer_properties.psd_width with self.layer_properties.width(). Same idea for the height. Test should now pass. https://github.com/chinedufn/psd/blob/930d00117fa9d625ebb1f006066437ec3156d2f2/src/sections/layer_and_mask_information_section/layer.rs#L457-L463