From 543b0de0b447226eb6ff489eeb68ae51a45f45bd Mon Sep 17 00:00:00 2001 From: jayzed80 Date: Fri, 30 Oct 2026 17:43:38 +0000 Subject: [PATCH] fix(eps): bitshift by the most negative integer no longer overflows on negation Negating i64::MIN panicked in debug builds. Use saturating_neg, as Op::Neg already does. --- crates/eps/src/import/interp.rs | 2 +- crates/eps/src/import/tests.rs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/eps/src/import/interp.rs b/crates/eps/src/import/interp.rs index f4c210b9c..75f7c7d13 100644 --- a/crates/eps/src/import/interp.rs +++ b/crates/eps/src/import/interp.rs @@ -816,7 +816,7 @@ impl<'a> Interp<'a> { }, Bitshift => { let (s, v) = (self.pop_int()?, self.pop_int()?); - let r = if s >= 0 { v.checked_shl(s.min(63) as u32) } else { v.checked_shr((-s).min(63) as u32) }; + let r = if s >= 0 { v.checked_shl(s.min(63) as u32) } else { v.checked_shr(s.saturating_neg().min(63) as u32) }; self.push(Obj::Int(r.unwrap_or(0)))?; } True => self.push(Obj::Bool(true))?, diff --git a/crates/eps/src/import/tests.rs b/crates/eps/src/import/tests.rs index 8f9cb5581..86fa8e35d 100644 --- a/crates/eps/src/import/tests.rs +++ b/crates/eps/src/import/tests.rs @@ -1400,3 +1400,10 @@ fn stored_graphics_states_use_up_the_memory_budget() { assert!(r.warnings.iter().any(|w| w.contains("uses too much memory")), "{body}: {:?}", r.warnings); } } + +/// `bitshift` by the most negative integer shifts right by everything, not a negation overflow. +#[test] +fn bitshift_by_the_most_negative_integer_does_not_panic() { + let r = read("0 0 10 10 rectfill 1 -9223372036854775808 bitshift pop -1 -9223372036854775808 bitshift pop"); + assert_eq!(objects(&r.document).len(), 1, "{:?}", r.warnings); +}