about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAdolfo OchagavĂ­a <aochagavia92@gmail.com>2014-10-27 16:04:55 +0100
committerAdolfo OchagavĂ­a <aochagavia92@gmail.com>2014-10-27 16:09:21 +0100
commitb8c4eb3a4e3bf53b220578d69d76a5a2e7f414f5 (patch)
treea4e33a9245527a027f4bb5925ac3ed3980b3b77e /src/libstd
parenta93e9c20f2a79eacad21592d0eb58e1a89648629 (diff)
downloadrust-b8c4eb3a4e3bf53b220578d69d76a5a2e7f414f5.tar.gz
rust-b8c4eb3a4e3bf53b220578d69d76a5a2e7f414f5.zip
Fix undefined behavior in std::ascii
Closes https://github.com/rust-lang/rust/issues/18314
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ascii.rs23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 07be15486fd..f7a84fc3478 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -247,8 +247,7 @@ impl OwnedAsciiCast for String {
 
     #[inline]
     unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
-        let v: Vec<u8> = mem::transmute(self);
-        v.into_ascii_nocheck()
+        self.into_bytes().into_ascii_nocheck()
     }
 }
 
@@ -260,7 +259,14 @@ impl OwnedAsciiCast for Vec<u8> {
 
     #[inline]
     unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
-        mem::transmute(self)
+        let v = Vec::from_raw_parts(self.len(),
+                                    self.capacity(),
+                                    mem::transmute(self.as_ptr()));
+
+        // We forget `self` to avoid freeing it at the end of the scope
+        // Otherwise, the returned `Vec` would point to freed memory
+        mem::forget(self);
+        v
     }
 }
 
@@ -338,7 +344,16 @@ pub trait IntoBytes {
 
 impl IntoBytes for Vec<Ascii> {
     fn into_bytes(self) -> Vec<u8> {
-        unsafe { mem::transmute(self) }
+        unsafe {
+            let v = Vec::from_raw_parts(self.len(),
+                                        self.capacity(),
+                                        mem::transmute(self.as_ptr()));
+
+            // We forget `self` to avoid freeing it at the end of the scope
+            // Otherwise, the returned `Vec` would point to freed memory
+            mem::forget(self);
+            v
+        }
     }
 }