Skip to content

Commit

Permalink
fix panic safety issue: guard against double drop (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
JOE1994 authored Jan 11, 2021
1 parent 7375e9f commit bacf18e
Showing 1 changed file with 38 additions and 34 deletions.
72 changes: 38 additions & 34 deletions matrix/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ extern crate basic_dsp_vector;

use basic_dsp_vector::numbers::*;
use basic_dsp_vector::*;
use std::{mem, ptr};
use std::{
mem::ManuallyDrop,
ptr
};

mod mat_impl;
pub use self::mat_impl::*;
Expand Down Expand Up @@ -230,25 +233,24 @@ impl<S, D> TransformContent<S, D> for [S; 2] {
where
F: FnMut(S) -> D,
{
let self_forget = ManuallyDrop::new(self);
unsafe {
let result = [
conversion(ptr::read(&self[0])),
conversion(ptr::read(&self[1])),
];
mem::forget(self);
result
[
conversion(ptr::read(&self_forget[0])),
conversion(ptr::read(&self_forget[1])),
]
}
}

fn transform_res<F>(self, mut conversion: F) -> TransRes<Self::Output>
where
F: FnMut(S) -> TransRes<D>,
{
let self_forget = ManuallyDrop::new(self);
unsafe {
let mut error = None;
let first = try_conv!(conversion(ptr::read(&self[0])), error);
let second = try_conv!(conversion(ptr::read(&self[1])), error);
mem::forget(self);
let first = try_conv!(conversion(ptr::read(&self_forget[0])), error);
let second = try_conv!(conversion(ptr::read(&self_forget[1])), error);

match error {
None => Ok([first, second]),
Expand All @@ -265,27 +267,28 @@ impl<S, D> TransformContent<S, D> for [S; 3] {
where
F: FnMut(S) -> D,
{
let self_forget = ManuallyDrop::new(self);

unsafe {
let result = [
conversion(ptr::read(&self[0])),
conversion(ptr::read(&self[1])),
conversion(ptr::read(&self[2])),
];
mem::forget(self);
result
[
conversion(ptr::read(&self_forget[0])),
conversion(ptr::read(&self_forget[1])),
conversion(ptr::read(&self_forget[2])),
]
}
}

fn transform_res<F>(self, mut conversion: F) -> TransRes<Self::Output>
where
F: FnMut(S) -> TransRes<D>,
{
let self_forget = ManuallyDrop::new(self);

unsafe {
let mut error = None;
let first = try_conv!(conversion(ptr::read(&self[0])), error);
let second = try_conv!(conversion(ptr::read(&self[1])), error);
let third = try_conv!(conversion(ptr::read(&self[2])), error);
mem::forget(self);
let first = try_conv!(conversion(ptr::read(&self_forget[0])), error);
let second = try_conv!(conversion(ptr::read(&self_forget[1])), error);
let third = try_conv!(conversion(ptr::read(&self_forget[2])), error);

match error {
None => Ok([first, second, third]),
Expand All @@ -302,29 +305,30 @@ impl<S, D> TransformContent<S, D> for [S; 4] {
where
F: FnMut(S) -> D,
{
let self_forget = ManuallyDrop::new(self);

unsafe {
let result = [
conversion(ptr::read(&self[0])),
conversion(ptr::read(&self[1])),
conversion(ptr::read(&self[2])),
conversion(ptr::read(&self[3])),
];
mem::forget(self);
result
[
conversion(ptr::read(&self_forget[0])),
conversion(ptr::read(&self_forget[1])),
conversion(ptr::read(&self_forget[2])),
conversion(ptr::read(&self_forget[3])),
]
}
}

fn transform_res<F>(self, mut conversion: F) -> TransRes<Self::Output>
where
F: FnMut(S) -> TransRes<D>,
{
let self_forget = ManuallyDrop::new(self);

unsafe {
let mut error = None;
let first = try_conv!(conversion(ptr::read(&self[0])), error);
let second = try_conv!(conversion(ptr::read(&self[1])), error);
let third = try_conv!(conversion(ptr::read(&self[2])), error);
let fourth = try_conv!(conversion(ptr::read(&self[3])), error);
mem::forget(self);
let first = try_conv!(conversion(ptr::read(&self_forget[0])), error);
let second = try_conv!(conversion(ptr::read(&self_forget[1])), error);
let third = try_conv!(conversion(ptr::read(&self_forget[2])), error);
let fourth = try_conv!(conversion(ptr::read(&self_forget[3])), error);

match error {
None => Ok([first, second, third, fourth]),
Expand Down

0 comments on commit bacf18e

Please sign in to comment.