1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 01:32:57 +01:00

Reduced unsafe converage (#520)

This commit is contained in:
Ashley 2018-09-26 20:56:34 +12:00 committed by Douman
parent 1b298142e3
commit 782eeb5ded
5 changed files with 121 additions and 99 deletions

View File

@ -209,31 +209,35 @@ impl<T> Node<T> {
} }
fn insert<I>(&mut self, next_el: &mut Node<I>) { fn insert<I>(&mut self, next_el: &mut Node<I>) {
unsafe { let next: *mut Node<T> = next_el as *const _ as *mut _;
let next: *mut Node<T> = next_el as *const _ as *mut _;
if let Some(next2) = self.next { if let Some(next2) = self.next {
unsafe {
let n = next2.as_mut().unwrap(); let n = next2.as_mut().unwrap();
n.prev = Some(next); n.prev = Some(next);
next_el.next = Some(next2 as *mut _);
} }
self.next = Some(next); next_el.next = Some(next2 as *mut _);
}
self.next = Some(next);
unsafe {
let next: &mut Node<T> = &mut *next; let next: &mut Node<T> = &mut *next;
next.prev = Some(self as *mut _); next.prev = Some(self as *mut _);
} }
} }
fn remove(&mut self) { fn remove(&mut self) {
unsafe { self.element = ptr::null_mut();
self.element = ptr::null_mut(); let next = self.next.take();
let next = self.next.take(); let prev = self.prev.take();
let prev = self.prev.take();
if let Some(prev) = prev { if let Some(prev) = prev {
unsafe {
prev.as_mut().unwrap().next = next; prev.as_mut().unwrap().next = next;
} }
if let Some(next) = next { }
if let Some(next) = next {
unsafe {
next.as_mut().unwrap().prev = prev; next.as_mut().unwrap().prev = prev;
} }
} }

View File

@ -196,45 +196,49 @@ impl<T: AsyncWrite, H: 'static> Writer for H1Writer<T, H> {
let mut pos = 0; let mut pos = 0;
let mut has_date = false; let mut has_date = false;
let mut remaining = buffer.remaining_mut(); let mut remaining = buffer.remaining_mut();
unsafe { let mut buf = unsafe { &mut *(buffer.bytes_mut() as *mut [u8]) };
let mut buf = &mut *(buffer.bytes_mut() as *mut [u8]); for (key, value) in msg.headers() {
for (key, value) in msg.headers() { match *key {
match *key { TRANSFER_ENCODING => continue,
TRANSFER_ENCODING => continue, CONTENT_ENCODING => if encoding != ContentEncoding::Identity {
CONTENT_ENCODING => if encoding != ContentEncoding::Identity { continue;
continue; },
}, CONTENT_LENGTH => match info.length {
CONTENT_LENGTH => match info.length { ResponseLength::None => (),
ResponseLength::None => (), _ => continue,
_ => continue, },
}, DATE => {
DATE => { has_date = true;
has_date = true;
}
_ => (),
} }
_ => (),
}
let v = value.as_ref(); let v = value.as_ref();
let k = key.as_str().as_bytes(); let k = key.as_str().as_bytes();
let len = k.len() + v.len() + 4; let len = k.len() + v.len() + 4;
if len > remaining { if len > remaining {
unsafe {
buffer.advance_mut(pos); buffer.advance_mut(pos);
pos = 0; }
buffer.reserve(len); pos = 0;
remaining = buffer.remaining_mut(); buffer.reserve(len);
remaining = buffer.remaining_mut();
unsafe {
buf = &mut *(buffer.bytes_mut() as *mut _); buf = &mut *(buffer.bytes_mut() as *mut _);
} }
buf[pos..pos + k.len()].copy_from_slice(k);
pos += k.len();
buf[pos..pos + 2].copy_from_slice(b": ");
pos += 2;
buf[pos..pos + v.len()].copy_from_slice(v);
pos += v.len();
buf[pos..pos + 2].copy_from_slice(b"\r\n");
pos += 2;
remaining -= len;
} }
buf[pos..pos + k.len()].copy_from_slice(k);
pos += k.len();
buf[pos..pos + 2].copy_from_slice(b": ");
pos += 2;
buf[pos..pos + v.len()].copy_from_slice(v);
pos += v.len();
buf[pos..pos + 2].copy_from_slice(b"\r\n");
pos += 2;
remaining -= len;
}
unsafe {
buffer.advance_mut(pos); buffer.advance_mut(pos);
} }

View File

@ -29,20 +29,24 @@ pub(crate) fn write_status_line(version: Version, mut n: u16, bytes: &mut BytesM
let lut_ptr = DEC_DIGITS_LUT.as_ptr(); let lut_ptr = DEC_DIGITS_LUT.as_ptr();
let four = n > 999; let four = n > 999;
// decode 2 more chars, if > 2 chars
let d1 = (n % 100) << 1;
n /= 100;
curr -= 2;
unsafe { unsafe {
// decode 2 more chars, if > 2 chars
let d1 = (n % 100) << 1;
n /= 100;
curr -= 2;
ptr::copy_nonoverlapping(lut_ptr.offset(d1 as isize), buf_ptr.offset(curr), 2); ptr::copy_nonoverlapping(lut_ptr.offset(d1 as isize), buf_ptr.offset(curr), 2);
}
// decode last 1 or 2 chars // decode last 1 or 2 chars
if n < 10 { if n < 10 {
curr -= 1; curr -= 1;
unsafe {
*buf_ptr.offset(curr) = (n as u8) + b'0'; *buf_ptr.offset(curr) = (n as u8) + b'0';
} else { }
let d1 = n << 1; } else {
curr -= 2; let d1 = n << 1;
curr -= 2;
unsafe {
ptr::copy_nonoverlapping( ptr::copy_nonoverlapping(
lut_ptr.offset(d1 as isize), lut_ptr.offset(d1 as isize),
buf_ptr.offset(curr), buf_ptr.offset(curr),
@ -107,47 +111,55 @@ pub fn write_content_length(mut n: usize, bytes: &mut BytesMut) {
} }
pub(crate) fn convert_usize(mut n: usize, bytes: &mut BytesMut) { pub(crate) fn convert_usize(mut n: usize, bytes: &mut BytesMut) {
unsafe { let mut curr: isize = 39;
let mut curr: isize = 39; let mut buf: [u8; 41] = unsafe { mem::uninitialized() };
let mut buf: [u8; 41] = mem::uninitialized(); buf[39] = b'\r';
buf[39] = b'\r'; buf[40] = b'\n';
buf[40] = b'\n'; let buf_ptr = buf.as_mut_ptr();
let buf_ptr = buf.as_mut_ptr(); let lut_ptr = DEC_DIGITS_LUT.as_ptr();
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
// eagerly decode 4 characters at a time // eagerly decode 4 characters at a time
while n >= 10_000 { while n >= 10_000 {
let rem = (n % 10_000) as isize; let rem = (n % 10_000) as isize;
n /= 10_000; n /= 10_000;
let d1 = (rem / 100) << 1; let d1 = (rem / 100) << 1;
let d2 = (rem % 100) << 1; let d2 = (rem % 100) << 1;
curr -= 4; curr -= 4;
unsafe {
ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2); ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2);
} }
}
// if we reach here numbers are <= 9999, so at most 4 chars long // if we reach here numbers are <= 9999, so at most 4 chars long
let mut n = n as isize; // possibly reduce 64bit math let mut n = n as isize; // possibly reduce 64bit math
// decode 2 more chars, if > 2 chars // decode 2 more chars, if > 2 chars
if n >= 100 { if n >= 100 {
let d1 = (n % 100) << 1; let d1 = (n % 100) << 1;
n /= 100; n /= 100;
curr -= 2; curr -= 2;
unsafe {
ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
} }
}
// decode last 1 or 2 chars // decode last 1 or 2 chars
if n < 10 { if n < 10 {
curr -= 1; curr -= 1;
unsafe {
*buf_ptr.offset(curr) = (n as u8) + b'0'; *buf_ptr.offset(curr) = (n as u8) + b'0';
} else { }
let d1 = n << 1; } else {
curr -= 2; let d1 = n << 1;
curr -= 2;
unsafe {
ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
} }
}
unsafe {
bytes.extend_from_slice(slice::from_raw_parts( bytes.extend_from_slice(slice::from_raw_parts(
buf_ptr.offset(curr), buf_ptr.offset(curr),
41 - curr as usize, 41 - curr as usize,

View File

@ -396,27 +396,29 @@ pub trait IoStream: AsyncRead + AsyncWrite + 'static {
if buf.remaining_mut() < LW_BUFFER_SIZE { if buf.remaining_mut() < LW_BUFFER_SIZE {
buf.reserve(HW_BUFFER_SIZE); buf.reserve(HW_BUFFER_SIZE);
} }
unsafe {
match self.read(buf.bytes_mut()) { let read = unsafe { self.read(buf.bytes_mut()) };
Ok(n) => { match read {
if n == 0 { Ok(n) => {
return Ok(Async::Ready((read_some, true))); if n == 0 {
} else { return Ok(Async::Ready((read_some, true)));
read_some = true; } else {
read_some = true;
unsafe {
buf.advance_mut(n); buf.advance_mut(n);
} }
} }
Err(e) => { }
return if e.kind() == io::ErrorKind::WouldBlock { Err(e) => {
if read_some { return if e.kind() == io::ErrorKind::WouldBlock {
Ok(Async::Ready((read_some, false))) if read_some {
} else { Ok(Async::Ready((read_some, false)))
Ok(Async::NotReady)
}
} else { } else {
Err(e) Ok(Async::NotReady)
}; }
} } else {
Err(e)
};
} }
} }
} }

View File

@ -148,7 +148,7 @@ impl Quoter {
if let Some(data) = cloned { if let Some(data) = cloned {
// Unsafe: we get data from http::Uri, which does utf-8 checks already // Unsafe: we get data from http::Uri, which does utf-8 checks already
// this code only decodes valid pct encoded values // this code only decodes valid pct encoded values
Some(unsafe { Rc::new(String::from_utf8_unchecked(data)) }) Some(Rc::new(unsafe { String::from_utf8_unchecked(data) }))
} else { } else {
None None
} }