Skip to content

Commit 0f25ccb

Browse files
committed
Add destructor bombs
1 parent b7c0848 commit 0f25ccb

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

src/lib.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,37 @@ pub enum Branch<L, R> {
161161
Right(R)
162162
}
163163

164+
impl <E, P> Drop for Chan<E, P> {
165+
fn drop(&mut self) {
166+
panic!("Session channel prematurely dropped");
167+
}
168+
}
169+
164170
impl<E> Chan<E, Eps> {
165171
/// Close a channel. Should always be used at the end of your program.
166-
pub fn close(self) {
167-
// Consume `c`
172+
pub fn close(mut self) {
173+
// This method cleans up the channel without running the panicky destructor
174+
// In essence, it calls the drop glue bypassing the `Drop::drop` method
175+
use std::mem;
176+
177+
// Create some dummy values to place the real things inside
178+
// This is safe because nobody will read these
179+
// mem::swap uses a similar technique (also paired with `forget()`)
180+
let mut sender = unsafe { mem::uninitialized() };
181+
let mut receiver = unsafe { mem::uninitialized() };
182+
183+
// Extract the internal sender/receiver so that we can drop them
184+
// We cannot drop directly since moving out of a type
185+
// that implements `Drop` is disallowed
186+
mem::swap(&mut self.0, &mut sender);
187+
mem::swap(&mut self.1, &mut receiver);
188+
189+
drop(sender);drop(receiver); // drop them
190+
191+
// Ensure Chan destructors don't run so that we don't panic
192+
// This also ensures that the uninitialized values don't get
193+
// read at any point
194+
mem::forget(self);
168195
}
169196
}
170197

0 commit comments

Comments
 (0)