diff --git a/skrifa/src/outline/glyf/hint/engine/graphics.rs b/skrifa/src/outline/glyf/hint/engine/graphics.rs index e7f659331..e47e84e3f 100644 --- a/skrifa/src/outline/glyf/hint/engine/graphics.rs +++ b/skrifa/src/outline/glyf/hint/engine/graphics.rs @@ -561,9 +561,15 @@ impl<'a> Engine<'a> { let selector = self.value_stack.pop()? as u32; let value = self.value_stack.pop()? as u32; // Selectors are indices starting with 1; not flags. + // Avoid potential subtract with overflow below. + // See + // and + if !(1..=3).contains(&selector) { + return Ok(()); + } // Convert index to flag. let selector_flag = 1 << (selector - 1); - if !(1..=3).contains(&selector) || (value != 0 && value != selector_flag) { + if value != 0 && value != selector_flag { return Ok(()); } // If preserving linear metrics, prevent modification of the backward @@ -1112,6 +1118,19 @@ mod tests { assert!(engine.graphics.backward_compatibility); } + // Subtract with overflow caught by fuzzing when selector == 0 + // See + // and + #[test] + fn instctrl_avoid_overflow() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.program.initial = Program::ControlValue; + engine.value_stack.push(0).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_instctrl().unwrap(); + } + #[test] fn scanctrl() { let mut mock = MockEngine::new();