Skip to content

Commit

Permalink
Fix potential out of bounds array access
Browse files Browse the repository at this point in the history
  • Loading branch information
birktj committed Feb 27, 2019
1 parent de18d44 commit bd0d66c
Showing 1 changed file with 28 additions and 3 deletions.
31 changes: 28 additions & 3 deletions src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ pub enum DecodingBuffer<'a> {
}

impl<'a> DecodingBuffer<'a> {
fn len(&self) -> usize {
match self {
DecodingBuffer::U8(ref buf) => buf.len(),
DecodingBuffer::U16(ref buf) => buf.len(),
}
}

fn byte_len(&self) -> usize {
match self {
DecodingBuffer::U8(ref buf) => 1,
DecodingBuffer::U16(ref buf) => 2,
}
}

fn copy<'b>(&'b mut self) -> DecodingBuffer<'b> where 'a: 'b {
match self {
DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(buf),
Expand Down Expand Up @@ -481,6 +495,11 @@ impl<R: Read + Seek> Decoder<R> {
},
method => return Err(TiffError::UnsupportedError(TiffUnsupportedError::UnsupportedCompressionMethod(method)))
};

if bytes > max_uncompressed_length*buffer.byte_len() {
return Err(TiffError::FormatError(TiffFormatError::InconsistentSizesEncountered));
}

Ok(match (color_type, buffer) {
(ColorType:: RGB(8), DecodingBuffer::U8(ref mut buffer)) |
(ColorType::RGBA(8), DecodingBuffer::U8(ref mut buffer)) |
Expand Down Expand Up @@ -541,15 +560,21 @@ impl<R: Read + Seek> Decoder<R> {
self.initialize_strip_decoder()?;

let index = self.strip_decoder.as_ref().unwrap().strip_index;
let offset = self.strip_decoder.as_ref().unwrap().strip_offsets[index];
let byte_count = self.strip_decoder.as_ref().unwrap().strip_bytes[index];
let offset = *self.strip_decoder.as_ref().unwrap().strip_offsets.get(index)
.ok_or(TiffError::FormatError(TiffFormatError::InconsistentSizesEncountered))?;
let byte_count = *self.strip_decoder.as_ref().unwrap().strip_bytes.get(index)
.ok_or(TiffError::FormatError(TiffFormatError::InconsistentSizesEncountered))?;

let rows_per_strip = self.get_tag_u32(ifd::Tag::RowsPerStrip)
.unwrap_or(self.height) as usize;

let strip_height = std::cmp::min(rows_per_strip, self.height as usize - index * rows_per_strip);

let buffer_size = self.width as usize * strip_height * self.bits_per_sample.iter().count();
let buffer_size = self.width as usize * strip_height * self.bits_per_sample.len();

if buffer.len() < buffer_size || byte_count as usize > buffer_size*buffer.byte_len() {
return Err(TiffError::FormatError(TiffFormatError::InconsistentSizesEncountered));
}

let units_read = self.expand_strip(buffer.copy(), offset, byte_count, buffer_size)?;

Expand Down

0 comments on commit bd0d66c

Please sign in to comment.