about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-03-29 14:07:32 +0000
committerbors <bors@rust-lang.org>2021-03-29 14:07:32 +0000
commit7750402c5eaf9ed0a73cb34c8483df245c36ac7b (patch)
treee1690f6e3ca41a9e66ece5b1b9347e0be6e56f68
parent3aedcf06b73fc36feeebca3d579e1d2a6c40acc5 (diff)
parenta0ff4612f21e312362a3ffbec0a104b9937d700b (diff)
Auto merge of #83609 - klensy:c-str, r=m-ou-se
ffi::c_str removed bound checks on as_bytes, to_bytes

This removes bound checks on CString::as_bytes() and CStr::to_bytes() and adds test.
-rw-r--r--library/std/src/ffi/c_str.rs6
-rw-r--r--library/std/src/ffi/c_str/tests.rs16
2 files changed, 20 insertions, 2 deletions
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index 687ed61b959..ed4950c57a6 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -613,7 +613,8 @@ impl CString {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes(&self) -> &[u8] {
-        &self.inner[..self.inner.len() - 1]
+        // SAFETY: CString has a length at least 1
+        unsafe { self.inner.get_unchecked(..self.inner.len() - 1) }
     }
 
     /// Equivalent to [`CString::as_bytes()`] except that the
@@ -1322,7 +1323,8 @@ impl CStr {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_bytes(&self) -> &[u8] {
         let bytes = self.to_bytes_with_nul();
-        &bytes[..bytes.len() - 1]
+        // SAFETY: to_bytes_with_nul returns slice with length at least 1
+        unsafe { bytes.get_unchecked(..bytes.len() - 1) }
     }
 
     /// Converts this C string to a byte slice containing the trailing 0 byte.
diff --git a/library/std/src/ffi/c_str/tests.rs b/library/std/src/ffi/c_str/tests.rs
index 4dff3df63a8..4f7ba9ad437 100644
--- a/library/std/src/ffi/c_str/tests.rs
+++ b/library/std/src/ffi/c_str/tests.rs
@@ -193,3 +193,19 @@ fn cstr_index_from_empty() {
     let cstr = CStr::from_bytes_with_nul(original).unwrap();
     let _ = &cstr[original.len()..];
 }
+
+#[test]
+fn c_string_from_empty_string() {
+    let original = "";
+    let cstring = CString::new(original).unwrap();
+    assert_eq!(original.as_bytes(), cstring.as_bytes());
+    assert_eq!([b'\0'], cstring.as_bytes_with_nul());
+}
+
+#[test]
+fn c_str_from_empty_string() {
+    let original = b"\0";
+    let cstr = CStr::from_bytes_with_nul(original).unwrap();
+    assert_eq!([] as [u8; 0], cstr.to_bytes());
+    assert_eq!([b'\0'], cstr.to_bytes_with_nul());
+}