From 5a319f71edd868ecefd2c1792fb47c10a62c1895 Mon Sep 17 00:00:00 2001 From: max-ishere <47008271+max-ishere@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:02:35 +0200 Subject: [PATCH] pff2: Enforce glyphs to be in sorted order --- src/parser/pff2.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/parser/pff2.rs b/src/parser/pff2.rs index 2ec584c..ee00897 100644 --- a/src/parser/pff2.rs +++ b/src/parser/pff2.rs @@ -175,18 +175,26 @@ impl Parser { const ENTRY_SIZE: usize = 4 + 1 + 4; if input.len() % ENTRY_SIZE != 0 { - return Err(ParserError::InvalidCharacterIndex); + return Err(ParserError::EmptyCharacterIndex); } + let mut last_codepoint = 0; + input .chunks(ENTRY_SIZE) .map(|chunk| { let codepoint = u32::from_be_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]); + if codepoint > last_codepoint { + last_codepoint = codepoint; + } else { + return Err(ParserError::CharacterIndexNotSortedAscending); + } + Ok::<_, ParserError>(CharIndex { code: char::from_u32(codepoint).ok_or(ParserError::InvalidCodepoint(codepoint))?, //code: u32::from_be_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]), - // skipp [4], it's a `storage_flags`, and GRUB never uses that field anyway + // skip [4], it's a `storage_flags`, and GRUB never uses that field anyway offset: u32::from_be_bytes([chunk[5], chunk[6], chunk[7], chunk[8]]).to_usize(), }) }) @@ -264,6 +272,18 @@ impl Parser { return Err(NoGlyphs); } + let mut last_codepoint = self.glyphs[0].code as u32; + + for Glyph { code, .. } in &self.glyphs[1..] { + let code = *code as u32; + + if code > last_codepoint { + last_codepoint = code; + } else { + return Err(GlyphsNotSortedAscending); + } + } + Ok(Font { name: self.name, family: self.family, @@ -327,7 +347,11 @@ pub enum ParserError { /// The size of the character index section doesnt divide evenly by the size of the individual elements #[error("Invalid data in the character index")] - InvalidCharacterIndex, + EmptyCharacterIndex, + + /// The character index section is required to contain codepoints in ascending order (`char as u32`) + #[error("Character index is not sorted in ascending order")] + CharacterIndexNotSortedAscending, /// The codepoint for a glyph entry was not valid UTF-8 #[error("Invalid unicode codepoint encountered: {0}")] @@ -360,6 +384,10 @@ pub enum FontValidationError { /// Font contains no glyphs or they could not be read #[error("Font contains no glyphs")] NoGlyphs, + + /// Font must store glyphs in sorted ascending order + #[error("Glyphs are not sorted in ascending order")] + GlyphsNotSortedAscending, } impl TryFrom<[u8; 4]> for SectionName {