From 782eeb5ded9bda6f41ad957315ce1e413873f83c Mon Sep 17 00:00:00 2001 From: Ashley Date: Wed, 26 Sep 2018 20:56:34 +1200 Subject: [PATCH] Reduced unsafe converage (#520) --- src/server/channel.rs | 26 +++++++------ src/server/h1writer.rs | 70 ++++++++++++++++++---------------- src/server/helpers.rs | 86 ++++++++++++++++++++++++------------------ src/server/mod.rs | 36 +++++++++--------- src/uri.rs | 2 +- 5 files changed, 121 insertions(+), 99 deletions(-) diff --git a/src/server/channel.rs b/src/server/channel.rs index 1795f8c2..3d753f65 100644 --- a/src/server/channel.rs +++ b/src/server/channel.rs @@ -209,31 +209,35 @@ impl Node { } fn insert(&mut self, next_el: &mut Node) { - unsafe { - let next: *mut Node = next_el as *const _ as *mut _; + let next: *mut Node = 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(); 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 = &mut *next; next.prev = Some(self as *mut _); } } fn remove(&mut self) { - unsafe { - self.element = ptr::null_mut(); - let next = self.next.take(); - let prev = self.prev.take(); + self.element = ptr::null_mut(); + let next = self.next.take(); + let prev = self.prev.take(); - if let Some(prev) = prev { + if let Some(prev) = prev { + unsafe { prev.as_mut().unwrap().next = next; } - if let Some(next) = next { + } + if let Some(next) = next { + unsafe { next.as_mut().unwrap().prev = prev; } } diff --git a/src/server/h1writer.rs b/src/server/h1writer.rs index 422f0ebc..72a68aeb 100644 --- a/src/server/h1writer.rs +++ b/src/server/h1writer.rs @@ -196,45 +196,49 @@ impl Writer for H1Writer { let mut pos = 0; let mut has_date = false; let mut remaining = buffer.remaining_mut(); - unsafe { - let mut buf = &mut *(buffer.bytes_mut() as *mut [u8]); - for (key, value) in msg.headers() { - match *key { - TRANSFER_ENCODING => continue, - CONTENT_ENCODING => if encoding != ContentEncoding::Identity { - continue; - }, - CONTENT_LENGTH => match info.length { - ResponseLength::None => (), - _ => continue, - }, - DATE => { - has_date = true; - } - _ => (), + let mut buf = unsafe { &mut *(buffer.bytes_mut() as *mut [u8]) }; + for (key, value) in msg.headers() { + match *key { + TRANSFER_ENCODING => continue, + CONTENT_ENCODING => if encoding != ContentEncoding::Identity { + continue; + }, + CONTENT_LENGTH => match info.length { + ResponseLength::None => (), + _ => continue, + }, + DATE => { + has_date = true; } + _ => (), + } - let v = value.as_ref(); - let k = key.as_str().as_bytes(); - let len = k.len() + v.len() + 4; - if len > remaining { + let v = value.as_ref(); + let k = key.as_str().as_bytes(); + let len = k.len() + v.len() + 4; + if len > remaining { + unsafe { buffer.advance_mut(pos); - pos = 0; - buffer.reserve(len); - remaining = buffer.remaining_mut(); + } + pos = 0; + buffer.reserve(len); + remaining = buffer.remaining_mut(); + unsafe { 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); } diff --git a/src/server/helpers.rs b/src/server/helpers.rs index f7e030f2..9c0b7f40 100644 --- a/src/server/helpers.rs +++ b/src/server/helpers.rs @@ -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 four = n > 999; + // decode 2 more chars, if > 2 chars + let d1 = (n % 100) << 1; + n /= 100; + curr -= 2; 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); + } - // decode last 1 or 2 chars - if n < 10 { - curr -= 1; + // decode last 1 or 2 chars + if n < 10 { + curr -= 1; + unsafe { *buf_ptr.offset(curr) = (n as u8) + b'0'; - } else { - let d1 = n << 1; - curr -= 2; + } + } else { + let d1 = n << 1; + curr -= 2; + unsafe { ptr::copy_nonoverlapping( lut_ptr.offset(d1 as isize), 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) { - unsafe { - let mut curr: isize = 39; - let mut buf: [u8; 41] = mem::uninitialized(); - buf[39] = b'\r'; - buf[40] = b'\n'; - let buf_ptr = buf.as_mut_ptr(); - let lut_ptr = DEC_DIGITS_LUT.as_ptr(); + let mut curr: isize = 39; + let mut buf: [u8; 41] = unsafe { mem::uninitialized() }; + buf[39] = b'\r'; + buf[40] = b'\n'; + let buf_ptr = buf.as_mut_ptr(); + let lut_ptr = DEC_DIGITS_LUT.as_ptr(); - // eagerly decode 4 characters at a time - while n >= 10_000 { - let rem = (n % 10_000) as isize; - n /= 10_000; + // eagerly decode 4 characters at a time + while n >= 10_000 { + let rem = (n % 10_000) as isize; + n /= 10_000; - let d1 = (rem / 100) << 1; - let d2 = (rem % 100) << 1; - curr -= 4; + let d1 = (rem / 100) << 1; + let d2 = (rem % 100) << 1; + curr -= 4; + unsafe { 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); } + } - // if we reach here numbers are <= 9999, so at most 4 chars long - let mut n = n as isize; // possibly reduce 64bit math + // if we reach here numbers are <= 9999, so at most 4 chars long + let mut n = n as isize; // possibly reduce 64bit math - // decode 2 more chars, if > 2 chars - if n >= 100 { - let d1 = (n % 100) << 1; - n /= 100; - curr -= 2; + // decode 2 more chars, if > 2 chars + if n >= 100 { + let d1 = (n % 100) << 1; + n /= 100; + curr -= 2; + unsafe { ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); } + } - // decode last 1 or 2 chars - if n < 10 { - curr -= 1; + // decode last 1 or 2 chars + if n < 10 { + curr -= 1; + unsafe { *buf_ptr.offset(curr) = (n as u8) + b'0'; - } else { - let d1 = n << 1; - curr -= 2; + } + } else { + let d1 = n << 1; + curr -= 2; + unsafe { ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); } + } + unsafe { bytes.extend_from_slice(slice::from_raw_parts( buf_ptr.offset(curr), 41 - curr as usize, diff --git a/src/server/mod.rs b/src/server/mod.rs index 009e06cc..96ec570a 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -396,27 +396,29 @@ pub trait IoStream: AsyncRead + AsyncWrite + 'static { if buf.remaining_mut() < LW_BUFFER_SIZE { buf.reserve(HW_BUFFER_SIZE); } - unsafe { - match self.read(buf.bytes_mut()) { - Ok(n) => { - if n == 0 { - return Ok(Async::Ready((read_some, true))); - } else { - read_some = true; + + let read = unsafe { self.read(buf.bytes_mut()) }; + match read { + Ok(n) => { + if n == 0 { + return Ok(Async::Ready((read_some, true))); + } else { + read_some = true; + unsafe { buf.advance_mut(n); } } - Err(e) => { - return if e.kind() == io::ErrorKind::WouldBlock { - if read_some { - Ok(Async::Ready((read_some, false))) - } else { - Ok(Async::NotReady) - } + } + Err(e) => { + return if e.kind() == io::ErrorKind::WouldBlock { + if read_some { + Ok(Async::Ready((read_some, false))) } else { - Err(e) - }; - } + Ok(Async::NotReady) + } + } else { + Err(e) + }; } } } diff --git a/src/uri.rs b/src/uri.rs index 752ddad8..881cf20a 100644 --- a/src/uri.rs +++ b/src/uri.rs @@ -148,7 +148,7 @@ impl Quoter { if let Some(data) = cloned { // Unsafe: we get data from http::Uri, which does utf-8 checks already // 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 { None }