diff --git a/src/decoder/ifd.rs b/src/decoder/ifd.rs index 58965d1..444597e 100644 --- a/src/decoder/ifd.rs +++ b/src/decoder/ifd.rs @@ -198,9 +198,17 @@ impl Entry { if n > limits.decoding_buffer_size { return Err(TiffError::LimitsExceeded); } - decoder.goto_offset(self.r(bo).read_u32()?)?; - let string = decoder.read_string(n)?; - Ok(Ascii(string)) + if n <= 4 { + let mut buf = vec![0; n]; + self.r(bo).read_exact(&mut buf )?; + let v = String::from_utf8(buf)?; + let v = v.trim_matches(char::from(0)); + Ok(Ascii(v.into())) + } else { + decoder.goto_offset(self.r(bo).read_u32()?)?; + let string = decoder.read_string(n)?; + Ok(Ascii(string)) + } } _ => Err(TiffError::UnsupportedError( TiffUnsupportedError::UnsupportedDataType, diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index a2cd6a0..4175352 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -424,11 +424,13 @@ impl Decoder { /// Reads a string #[inline] pub fn read_string(&mut self, length: usize) -> TiffResult { - let mut out = String::with_capacity(length); - self.reader.read_to_string(&mut out)?; + let mut out = vec![0; length]; + self.reader.read_exact(&mut out)?; // Strings may be null-terminated, so we trim anything downstream of the null byte - let trimmed = out.bytes().take_while(|&n| n != 0).collect::>(); - Ok(String::from_utf8(trimmed)?) + if let Some(first) = out.iter().position(|&b| b == 0) { + out.truncate(first); + } + Ok(String::from_utf8(out)?) } /// Reads a TIFF IFA offset/value field