diff --git a/src/buffer_util.rs b/src/buffer_util.rs index 46330e0..9da7f4f 100644 --- a/src/buffer_util.rs +++ b/src/buffer_util.rs @@ -1,4 +1,4 @@ -use bytes::{Buf, BufMut}; +use bytes::{Buf, BufMut, TryGetError}; use four_cc::FourCC; pub use safer_bytes::{error::Truncated as TruncatedError, SafeBuf}; use thiserror::Error; @@ -21,6 +21,12 @@ impl From for Base128Error { } } +impl From for Base128Error { + fn from(_: TryGetError) -> Self { + Base128Error::Truncated + } +} + pub trait BufExt { fn get_four_cc(&mut self) -> FourCC; fn try_get_four_cc(&mut self) -> Result; @@ -76,11 +82,23 @@ where const ONE_MORE_BYTE_CODE_2: u8 = 254; const WORD_CODE: u8 = 253; const LOWEST_UCODE: u16 = 253; - let code = self.try_get_u8()?; + let code = self + .try_get_u8() + .map_err(|_| safer_bytes::error::Truncated {})?; match code { - WORD_CODE => self.try_get_u16(), - ONE_MORE_BYTE_CODE_1 => Ok(self.try_get_u8()? as u16 + LOWEST_UCODE), - ONE_MORE_BYTE_CODE_2 => Ok(self.try_get_u8()? as u16 + 2 * LOWEST_UCODE), + WORD_CODE => self + .try_get_u16() + .map_err(|_| safer_bytes::error::Truncated {}), + ONE_MORE_BYTE_CODE_1 => Ok(self + .try_get_u8() + .map_err(|_| safer_bytes::error::Truncated {})? + as u16 + + LOWEST_UCODE), + ONE_MORE_BYTE_CODE_2 => Ok(self + .try_get_u8() + .map_err(|_| safer_bytes::error::Truncated {})? + as u16 + + 2 * LOWEST_UCODE), _ => Ok(code as u16), } } diff --git a/src/glyf_decoder/mod.rs b/src/glyf_decoder/mod.rs index ccac27c..4b02d9d 100644 --- a/src/glyf_decoder/mod.rs +++ b/src/glyf_decoder/mod.rs @@ -186,16 +186,16 @@ impl<'a> Woff2GlyfDecoder<'a, &'a [u8]> { running_total_points += number_of_points; end_points_of_contours_stream.put_u16(running_total_points - 1); for _point_index in 0..number_of_points { - let flags = self.flag_stream.try_get_u8()?; + let flags = SafeBuf::try_get_u8(&mut self.flag_stream)?; let triplet = &COORD_LUT[(flags & 0x7f) as usize]; let data = match triplet.byte_count { - 1 => self.glyph_stream.try_get_u8()? as u32, - 2 => self.glyph_stream.try_get_u16()? as u32, + 1 => SafeBuf::try_get_u8(&mut self.glyph_stream)? as u32, + 2 => SafeBuf::try_get_u16(&mut self.glyph_stream)? as u32, 3 => { - ((self.glyph_stream.try_get_u8()? as u32) << 16) - | (self.glyph_stream.try_get_u16()? as u32) + ((SafeBuf::try_get_u8(&mut self.glyph_stream)? as u32) << 16) + | (SafeBuf::try_get_u16(&mut self.glyph_stream)? as u32) } - 4 => self.glyph_stream.try_get_u32()?, + 4 => SafeBuf::try_get_u32(&mut self.glyph_stream)?, _ => panic!(), }; let dx = triplet.dx(data); @@ -264,10 +264,10 @@ impl<'a> Woff2GlyfDecoder<'a, &'a [u8]> { .try_copy_to_buf(&mut instructions_stream, instruction_length as usize)?; if self.bbox_bitmap[glyph_index as usize] { - x_min = self.bbox_stream.try_get_i16()?; - y_min = self.bbox_stream.try_get_i16()?; - x_max = self.bbox_stream.try_get_i16()?; - y_max = self.bbox_stream.try_get_i16()?; + x_min = SafeBuf::try_get_i16(&mut self.bbox_stream)?; + y_min = SafeBuf::try_get_i16(&mut self.bbox_stream)?; + x_max = SafeBuf::try_get_i16(&mut self.bbox_stream)?; + y_max = SafeBuf::try_get_i16(&mut self.bbox_stream)?; } output_buffer.put_i16(number_of_contours); @@ -292,17 +292,17 @@ impl<'a> Woff2GlyfDecoder<'a, &'a [u8]> { ) -> Result<(), GlyfDecoderError> { output_buffer.put_i16(-1); if self.bbox_bitmap[glyph_index as usize] { - output_buffer.put_i16(self.bbox_stream.try_get_i16()?); - output_buffer.put_i16(self.bbox_stream.try_get_i16()?); - output_buffer.put_i16(self.bbox_stream.try_get_i16()?); - output_buffer.put_i16(self.bbox_stream.try_get_i16()?); + output_buffer.put_i16(SafeBuf::try_get_i16(&mut self.bbox_stream)?); + output_buffer.put_i16(SafeBuf::try_get_i16(&mut self.bbox_stream)?); + output_buffer.put_i16(SafeBuf::try_get_i16(&mut self.bbox_stream)?); + output_buffer.put_i16(SafeBuf::try_get_i16(&mut self.bbox_stream)?); } else { Err(GlyfDecoderError::CompositeGlyphWithoutBbox)? } let mut have_instructions = false; loop { - let flag_word = self.composite_stream.try_get_u16()?; + let flag_word = SafeBuf::try_get_u16(&mut self.composite_stream)?; let mut num_bytes = 4usize; if flag_word & 0x0001 == 0x0001 { @@ -345,7 +345,7 @@ impl<'a> Woff2GlyfDecoder<'a, &'a [u8]> { glyph_index: u16, output_vector: &mut Vec, ) -> Result<(), GlyfDecoderError> { - let number_of_contours = self.n_contour_stream.try_get_i16()?; + let number_of_contours = SafeBuf::try_get_i16(&mut self.n_contour_stream)?; match number_of_contours { 0 => Ok(()), num if num > 0 => { diff --git a/src/woff2/collection_directory.rs b/src/woff2/collection_directory.rs index af94fcd..b9c1a4c 100644 --- a/src/woff2/collection_directory.rs +++ b/src/woff2/collection_directory.rs @@ -4,7 +4,7 @@ use bytes::{Buf, BufMut}; use four_cc::FourCC; use thiserror::Error; -use crate::buffer_util::{BufExt, SafeBuf, TruncatedError}; +use crate::buffer_util::{BufExt, TruncatedError}; use crate::ttf_header::{TableDirectory, TableRecord}; #[derive(Debug, Error)] @@ -55,7 +55,10 @@ impl CollectionHeader { buf: &mut impl Buf, total_num_tables: u16, ) -> Result { - let version = buf.try_get_u32()?.try_into()?; + let version = buf + .try_get_u32() + .map_err(|_| CollectionHeaderError::Truncated)? + .try_into()?; let num_fonts = buf.try_get_255_u16()?; let fonts = (0..num_fonts) .map(|_| { diff --git a/src/woff2/table_directory.rs b/src/woff2/table_directory.rs index fc5672b..3702fe4 100644 --- a/src/woff2/table_directory.rs +++ b/src/woff2/table_directory.rs @@ -5,7 +5,7 @@ use four_cc::FourCC; use thiserror::Error; use crate::{ - buffer_util::{pad_to_multiple_of_four, Base128Error, BufExt, SafeBuf, TruncatedError}, + buffer_util::{pad_to_multiple_of_four, Base128Error, BufExt, TruncatedError}, checksum::{calculate_checksum, set_checksum_adjustment, ChecksumError}, glyf_decoder::{decode_glyf_table, GlyfDecoderError}, ttf_header::TableRecord, @@ -188,7 +188,9 @@ struct PartialTableDirectoryEntry { impl PartialTableDirectoryEntry { fn from_buf(buffer: &mut impl Buf) -> Result { - let flags = buffer.try_get_u8()?; + let flags = buffer + .try_get_u8() + .map_err(|_| TableDirectoryError::Truncated)?; let preprocessing_transformation_version = flags & 0xC0; let table_ref = flags & 0x3f; let tag = if table_ref == 0x3f {