From 3a585f19d3f955a3b21d83a98aca9e75e9070027 Mon Sep 17 00:00:00 2001 From: scadastrangelove Date: Mon, 20 Jul 2026 11:10:47 +0300 Subject: [PATCH] Guard CFF2 BLEND operator against empty argument stack VS_INDEX checks p.stack.len() != 1 before its pop; BLEND popped unconditionally to read its operand count, hitting the mandatory slice bounds check once len wraps to usize::MAX -- same root cause as #80 (fixed by f28f7a5), which only touched cff1.rs's seac path and left cff2.rs's BLEND operator unguarded. Discovered by the rust-in-peace security pipeline (https://github.com/scadastrangelove/rust-in-peace/). --- src/tables/cff/cff2.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tables/cff/cff2.rs b/src/tables/cff/cff2.rs index 68e7a20..199cd13 100644 --- a/src/tables/cff/cff2.rs +++ b/src/tables/cff/cff2.rs @@ -380,6 +380,10 @@ fn _parse_char_string( ctx.had_blend = true; + if p.stack.is_empty() { + return Err(CFFError::InvalidArgumentsStackLength); + } + let n = u16::try_num_from(p.stack.pop()) .ok_or(CFFError::InvalidNumberOfBlendOperands)?; let k = ctx.scalars.len();