Skip to content

Commit

Permalink
Option to ignore ancillary chunks with invalid CRC (#430)
Browse files Browse the repository at this point in the history
Skipping non-critical chunks if the CRC check fails
is the default it libpng. Therefore adding this
option and enabling it by default.

image-rs/image#2057
  • Loading branch information
sophie-h authored Nov 26, 2023
1 parent 8afa7ef commit b93777c
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/decoder/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ pub struct DecodeOptions {
ignore_adler32: bool,
ignore_crc: bool,
ignore_text_chunk: bool,
skip_ancillary_crc_failures: bool,
}

impl Default for DecodeOptions {
Expand All @@ -393,6 +394,7 @@ impl Default for DecodeOptions {
ignore_adler32: true,
ignore_crc: false,
ignore_text_chunk: false,
skip_ancillary_crc_failures: true,
}
}
}
Expand Down Expand Up @@ -425,6 +427,13 @@ impl DecodeOptions {
pub fn set_ignore_text_chunk(&mut self, ignore_text_chunk: bool) {
self.ignore_text_chunk = ignore_text_chunk;
}

/// Ignore ancillary chunks if CRC fails
///
/// Defaults to `true`
pub fn set_skip_ancillary_crc_failures(&mut self, skip_ancillary_crc_failures: bool) {
self.skip_ancillary_crc_failures = skip_ancillary_crc_failures;
}
}

/// PNG StreamingDecoder (low-level interface)
Expand Down Expand Up @@ -530,6 +539,14 @@ impl StreamingDecoder {
self.decode_options.set_ignore_crc(ignore_crc)
}

/// Ignore ancillary chunks if CRC fails
///
/// Defaults to `true`
pub fn set_skip_ancillary_crc_failures(&mut self, skip_ancillary_crc_failures: bool) {
self.decode_options
.set_skip_ancillary_crc_failures(skip_ancillary_crc_failures)
}

/// Low level StreamingDecoder interface.
///
/// Allows to stream partial data to the encoder. Returns a tuple containing the bytes that have
Expand Down Expand Up @@ -647,6 +664,12 @@ impl StreamingDecoder {
} else {
Ok((1, Decoded::ChunkComplete(val, type_str)))
}
} else if self.decode_options.skip_ancillary_crc_failures
&& !chunk::is_critical(type_str)
{
// Ignore ancillary chunk with invalid CRC
self.state = Some(State::U32(U32ValueKind::Length));
Ok((1, Decoded::Nothing))
} else {
Err(DecodingError::Format(
FormatErrorInner::CrcMismatch {
Expand Down

0 comments on commit b93777c

Please sign in to comment.