Skip to content

ICO: Add header validation in strict mode#3033

Open
RunDevelopment wants to merge 2 commits into
image-rs:mainfrom
RunDevelopment:ico-header-valid
Open

ICO: Add header validation in strict mode#3033
RunDevelopment wants to merge 2 commits into
image-rs:mainfrom
RunDevelopment:ico-header-valid

Conversation

@RunDevelopment

Copy link
Copy Markdown
Member

This PR adds more validation for the ICO header in strict mode.

Changes:

  • The reserved first two bytes are now checked to be zero.
  • The type is now checked to be either ICO or CUR.

@197g 197g left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appreciate the idea, more validation to keep strict mode from changing behavior silently on reserved data 👍

Comment thread src/codecs/ico/decoder.rs
let count = u16::from_le_bytes(header[4..6].try_into().unwrap());
let mut header = header.as_slice();

let reserved = header.read_u16::<LittleEndian>()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use split_first_chunk here to instead of an IO-facing library. Alternatively, but only since this is uniformly u16, you might turn header into [[u8; 2]; 3] and read it with as_flattened? Lots of alternatives that do not involve an IO error for a statically sized array and constant condition.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, I just copied what TGA is doing. Should we not do that there too?

I also considered the u16 approach, but didn't like it because it makes it really easy to mess up endian. E.g.

let mut header = [0_u16; 3];
reader.read_exact(bytemuck::cast_slice_mut(&mut header))?;
let [reserved, id_type, entries] = header; // only correct on LE systems

But I agree with you that the IO interface is a little overkill. Maybe we could just have a 2 or 3 util methods like this:

// Panics when OOB
fn read_u16<Endian>(slice: &[u8], offset: usize) -> u16;

I saw this pattern in Chrome, so that might be an idea.

@RunDevelopment

Copy link
Copy Markdown
Member Author

Appreciate the idea, more validation to keep strict mode from changing behavior silently on reserved data 👍

That, and I want to lay the groundwork for supporting CUR files eventually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants