From b4abd1431a553be131c757b9b366c71dfd6461af Mon Sep 17 00:00:00 2001
From: Carl Lerche <me@carllerche.com>
Date: Sat, 25 Jul 2015 20:03:22 -0700
Subject: [PATCH] Mark `MutBuf::mut_buf` as unsafe

`MutBuf::mut_buf` allows access to uninitialized memory.
---
 src/buf/byte.rs  |  2 +-
 src/buf/mod.rs   | 14 +++++++-------
 src/buf/ring.rs  |  2 +-
 src/buf/slice.rs |  2 +-
 src/str/bytes.rs | 12 +++++-------
 test/test_buf.rs |  5 ++++-
 6 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/src/buf/byte.rs b/src/buf/byte.rs
index 106f574..e2993e3 100644
--- a/src/buf/byte.rs
+++ b/src/buf/byte.rs
@@ -321,7 +321,7 @@ impl MutBuf for MutByteBuf {
         self.buf.advance(cnt)
     }
 
-    fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
+    unsafe fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
         let pos = self.buf.pos();
         let lim = self.buf.lim();
         &mut self.buf.mem.bytes_mut()[pos..lim]
diff --git a/src/buf/mod.rs b/src/buf/mod.rs
index 07de5f8..2eab003 100644
--- a/src/buf/mod.rs
+++ b/src/buf/mod.rs
@@ -102,7 +102,9 @@ pub trait MutBuf : Sized {
 
     /// Returns a mutable slice starting at the current MutBuf position and of
     /// length between 0 and `MutBuf::remaining()`.
-    fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8];
+    ///
+    /// The returned byte slice may represent uninitialized memory.
+    unsafe fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8];
 
     /// Write bytes from the given slice into the `MutBuf` and advance the
     /// cursor by the number of bytes written.
@@ -268,7 +270,7 @@ impl<'a, R: io::Read+'a> Source for &'a mut R {
         let mut cnt = 0;
 
         while buf.has_remaining() {
-            let i = try!(self.read(buf.mut_bytes()));
+            let i = try!(self.read(unsafe { buf.mut_bytes() }));
 
             if i == 0 {
                 break;
@@ -349,7 +351,7 @@ impl MutBuf for Vec<u8> {
         }
     }
 
-    fn mut_bytes(&mut self) -> &mut [u8] {
+    unsafe fn mut_bytes(&mut self) -> &mut [u8] {
         use std::slice;
 
         if self.capacity() == self.len() {
@@ -359,10 +361,8 @@ impl MutBuf for Vec<u8> {
         let cap = self.capacity();
         let len = self.len();
 
-        unsafe {
-            let ptr = self.as_mut_ptr();
-            &mut slice::from_raw_parts_mut(ptr, cap)[len..]
-        }
+        let ptr = self.as_mut_ptr();
+        &mut slice::from_raw_parts_mut(ptr, cap)[len..]
     }
 }
 
diff --git a/src/buf/ring.rs b/src/buf/ring.rs
index a422093..926d054 100644
--- a/src/buf/ring.rs
+++ b/src/buf/ring.rs
@@ -196,7 +196,7 @@ impl MutBuf for RingBuf {
         self.advance_writer(cnt)
     }
 
-    fn mut_bytes(&mut self) -> &mut [u8] {
+    unsafe fn mut_bytes(&mut self) -> &mut [u8] {
         if self.cap == 0 {
             return self.ptr.bytes_mut();
         }
diff --git a/src/buf/slice.rs b/src/buf/slice.rs
index eaa2cf3..fb117ff 100644
--- a/src/buf/slice.rs
+++ b/src/buf/slice.rs
@@ -53,7 +53,7 @@ impl<'a> MutBuf for MutSliceBuf<'a> {
         self.pos += cnt;
     }
 
-    fn mut_bytes<'b>(&'b mut self) -> &'b mut [u8] {
+    unsafe fn mut_bytes<'b>(&'b mut self) -> &'b mut [u8] {
         &mut self.bytes[self.pos..]
     }
 }
diff --git a/src/str/bytes.rs b/src/str/bytes.rs
index a0bef44..42e1756 100644
--- a/src/str/bytes.rs
+++ b/src/str/bytes.rs
@@ -208,17 +208,15 @@ impl<'a> Source for &'a Bytes {
         while src.has_remaining() && dst.has_remaining() {
             let l;
 
-            {
+            unsafe {
                 let s = src.bytes();
                 let d = dst.mut_bytes();
                 l = cmp::min(s.len(), d.len());
 
-                unsafe {
-                    ptr::copy_nonoverlapping(
-                        s.as_ptr(),
-                        d.as_mut_ptr(),
-                        l);
-                }
+                ptr::copy_nonoverlapping(
+                    s.as_ptr(),
+                    d.as_mut_ptr(),
+                    l);
             }
 
             src.advance(l);
diff --git a/test/test_buf.rs b/test/test_buf.rs
index 93689ac..592bc0d 100644
--- a/test/test_buf.rs
+++ b/test/test_buf.rs
@@ -30,7 +30,10 @@ pub fn test_vec_as_mut_buf() {
     let mut buf = vec![];
 
     assert_eq!(buf.remaining(), usize::MAX);
-    assert_eq!(buf.mut_bytes().len(), 64);
+
+    unsafe {
+        assert_eq!(buf.mut_bytes().len(), 64);
+    }
 
     buf.write(&b"zomg"[..]).unwrap();
 
-- 
GitLab