From 2f620f8f31eb0a97ee0a26195439a6e48b06fbbe Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Fri, 23 Oct 2026 02:24:22 +0000 Subject: [PATCH] Restore render depth counters after a caught panic Fixes #3598 Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/render/src/lib.rs | 1 + crates/render/src/pattern.rs | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/render/src/lib.rs b/crates/render/src/lib.rs index eaa31c5c5..fcb73fff5 100644 --- a/crates/render/src/lib.rs +++ b/crates/render/src/lib.rs @@ -734,6 +734,7 @@ impl Renderer { /// Start a frame: cache entries used from now on are marked with its stamp. fn begin_frame(&mut self) { self.stamp += 1; + self.inline_depth = 0; } /// End a frame: drop cache entries not used for a few frames (every render, thumbnails too, diff --git a/crates/render/src/pattern.rs b/crates/render/src/pattern.rs index 9cb5e874f..e6ea284ba 100644 --- a/crates/render/src/pattern.rs +++ b/crates/render/src/pattern.rs @@ -205,10 +205,18 @@ fn with_tile_renderer(f: impl FnOnce(&mut Renderer) -> T) -> Option { })) })?; let mut r = r; + // Restores the depth even if `f` panics and the panic is caught (the renderer is then dropped). + struct Restore; + impl Drop for Restore { + fn drop(&mut self) { + CACHE.with(|c| c.borrow_mut().depth -= 1); + } + } + let guard = Restore; let out = f(&mut r); + drop(guard); CACHE.with(|c| { let mut c = c.borrow_mut(); - c.depth -= 1; if c.renderer.is_none() { c.renderer = Some(r); } @@ -687,4 +695,13 @@ mod tests { assert_eq!(raster_scale(2.1, (10.0, 10.0)), raster_scale(3.9, (10.0, 10.0))); assert!(raster_scale(64.0, (1000.0, 10.0)) * 1000.0 <= MAX_TILE_PX); } + + #[test] + fn tile_renderer_depth_survives_caught_panics() { + for _ in 0..4 { + let r = std::panic::catch_unwind(|| with_tile_renderer(|_| panic!("tile boom"))); + assert!(r.is_err()); + } + assert!(with_tile_renderer(|_| ()).is_some(), "depth leaked after caught panics"); + } }