From 2f4e491874e98ac807530a2bc02496b53b6c308a Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Fri, 28 May 2021 20:32:30 +0100 Subject: [PATCH] Check for where tag count * tag size overflows --- src/decoder/ifd.rs | 33 ++++++++++++++++++++------------- tests/decode_images.rs | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/decoder/ifd.rs b/src/decoder/ifd.rs index 862616a..23416a4 100644 --- a/src/decoder/ifd.rs +++ b/src/decoder/ifd.rs @@ -349,19 +349,26 @@ impl Entry { } let bo = decoder.byte_order(); - let value_bytes = self.count - * match self.type_ { - Type::BYTE | Type::SBYTE | Type::ASCII | Type::UNDEFINED => 1, - Type::SHORT | Type::SSHORT => 2, - Type::LONG | Type::SLONG | Type::FLOAT | Type::IFD => 4, - Type::LONG8 - | Type::SLONG8 - | Type::DOUBLE - | Type::RATIONAL - | Type::SRATIONAL - | Type::IFD8 => 8, - Type::__NonExhaustive => unreachable!(), - }; + + let tag_size = match self.type_ { + Type::BYTE | Type::SBYTE | Type::ASCII | Type::UNDEFINED => 1, + Type::SHORT | Type::SSHORT => 2, + Type::LONG | Type::SLONG | Type::FLOAT | Type::IFD => 4, + Type::LONG8 + | Type::SLONG8 + | Type::DOUBLE + | Type::RATIONAL + | Type::SRATIONAL + | Type::IFD8 => 8, + Type::__NonExhaustive => unreachable!(), + }; + + let value_bytes = match self.count.checked_mul(tag_size) { + Some(n) => n, + None => { + return Err(TiffError::LimitsExceeded); + } + }; // Case 2: there is one value. if self.count == 1 { diff --git a/tests/decode_images.rs b/tests/decode_images.rs index 58ffc4a..bf23a2a 100644 --- a/tests/decode_images.rs +++ b/tests/decode_images.rs @@ -307,3 +307,21 @@ fn test_div_zero() { unexpected => panic!("Unexpected error {}", unexpected), } } + +#[test] +fn test_too_many_value_bytes() { + let image = [ + 73, 73, 43, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 8, 0, 0, 0, + 23, 0, 12, 0, 0, 65, 4, 0, 1, 6, 0, 0, 1, 16, 0, 1, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, 59, 73, 84, 186, 202, 83, 240, 66, 1, 53, 22, 56, 47, + 0, 0, 0, 0, 0, 0, 1, 222, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 4, 0, 0, 100, 0, + 0, 89, 89, 89, 89, 89, 89, 89, 89, 96, 1, 20, 89, 89, 89, 89, 18, + ]; + + let error = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + + match error { + tiff::TiffError::LimitsExceeded => {} + unexpected => panic!("Unexpected error {}", unexpected), + } +}