From 765b653bb676076ac790847d6593f1fcacc0fa4a Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Thu, 21 Nov 2019 20:58:11 +0100 Subject: [PATCH] Don't leak the recovery closure on filling a hole The thing can have a destructor (because the closure might capture things that have destructor themselves) and not running it might leak resources. --- src/scoped.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/scoped.rs b/src/scoped.rs index 4997c6a..2d50f0b 100644 --- a/src/scoped.rs +++ b/src/scoped.rs @@ -112,7 +112,7 @@ pub struct Hole<'c, 'm, T: 'm, F: FnOnce() -> T> { impl<'c, 'm, T: 'm, F: FnOnce() -> T> Hole<'c, 'm, T, F> { /// Fills the Hole. - pub fn fill(self, t: T) { + pub fn fill(mut self, t: T) { use std::ptr; use std::mem; @@ -121,7 +121,13 @@ impl<'c, 'm, T: 'm, F: FnOnce() -> T> Hole<'c, 'm, T, F> { } let num_holes = self.active_holes.get(); self.active_holes.set(num_holes - 1); + // The recovery is the only thing that *might* have a destructor to run. Make sure it is + // not forgotten. + let recovery = self.recovery.take(); mem::forget(self); + // But destroy it after getting rid of self. Otherwise panic in it might trigger destructor + // of us after we already filled the hole which would probably do very weird things. + drop(recovery); } } @@ -172,4 +178,4 @@ fn panic_on_recovered_panic() { }); })); assert!(result.is_err()); -} \ No newline at end of file +}