tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

unsafe_box.rs (1970B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 #![allow(unsafe_code)]
      6 
      7 use std::mem::ManuallyDrop;
      8 use std::ops::Deref;
      9 use std::ptr;
     10 
     11 /// An unsafe box, derefs to `T`.
     12 pub(super) struct UnsafeBox<T> {
     13    inner: ManuallyDrop<Box<T>>,
     14 }
     15 
     16 impl<T> UnsafeBox<T> {
     17    /// Creates a new unsafe box.
     18    pub(super) fn from_box(value: Box<T>) -> Self {
     19        Self {
     20            inner: ManuallyDrop::new(value),
     21        }
     22    }
     23 
     24    /// Creates a new box from a pointer.
     25    ///
     26    /// # Safety
     27    ///
     28    /// The input should point to a valid `T`.
     29    pub(super) unsafe fn from_raw(ptr: *mut T) -> Self {
     30        Self {
     31            inner: ManuallyDrop::new(Box::from_raw(ptr)),
     32        }
     33    }
     34 
     35    /// Creates a new unsafe box from an existing one.
     36    ///
     37    /// # Safety
     38    ///
     39    /// There is no refcounting or whatever else in an unsafe box, so this
     40    /// operation can lead to double frees.
     41    pub(super) unsafe fn clone(this: &Self) -> Self {
     42        Self {
     43            inner: ptr::read(&this.inner),
     44        }
     45    }
     46 
     47    /// Returns a mutable reference to the inner value of this unsafe box.
     48    ///
     49    /// # Safety
     50    ///
     51    /// Given `Self::clone`, nothing prevents anyone from creating
     52    /// multiple mutable references to the inner value, which is completely UB.
     53    pub(crate) unsafe fn deref_mut(this: &mut Self) -> &mut T {
     54        &mut this.inner
     55    }
     56 
     57    /// Drops the inner value of this unsafe box.
     58    ///
     59    /// # Safety
     60    ///
     61    /// Given this doesn't consume the unsafe box itself, this has the same
     62    /// safety caveats as `ManuallyDrop::drop`.
     63    pub(super) unsafe fn drop(this: &mut Self) {
     64        ManuallyDrop::drop(&mut this.inner)
     65    }
     66 }
     67 
     68 impl<T> Deref for UnsafeBox<T> {
     69    type Target = T;
     70 
     71    fn deref(&self) -> &Self::Target {
     72        &self.inner
     73    }
     74 }