From 1e47250540bc97f921d1b7e2982f1904fa191dff Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 1 May 2019 17:59:48 +0200 Subject: [PATCH] as_ptr returns a read-only pointer --- src/libcore/slice/mod.rs | 6 ++++++ src/libcore/str/mod.rs | 5 +++++ src/libstd/ffi/c_str.rs | 9 +++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 8731f486753..c273153fa5e 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -359,6 +359,10 @@ pub unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output /// The caller must ensure that the slice outlives the pointer this /// function returns, or else it will end up pointing to garbage. /// + /// The caller must also ensure that the memory the pointer (non-transitively) points to + /// is never written to (except inside an `UnsafeCell`). If you need to mutate + /// the contents of the slice, use [`as_mut_ptr`]. + /// /// Modifying the container referenced by this slice may cause its buffer /// to be reallocated, which would also make any pointers to it invalid. /// @@ -374,6 +378,8 @@ pub unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output /// } /// } /// ``` + /// + /// [`as_mut_ptr`]: #method.as_mut_ptr #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub const fn as_ptr(&self) -> *const T { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 45421848cec..96a5ce61ca0 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2188,7 +2188,12 @@ pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] { /// [`u8`]. This pointer will be pointing to the first byte of the string /// slice. /// + /// The caller must ensure that the memory the pointer points to + /// is never written to. If you need to mutate + /// the contents of the string slice, use [`as_mut_ptr`]. + /// /// [`u8`]: primitive.u8.html + /// [`as_mut_ptr`]: #method.as_mut_ptr /// /// # Examples /// diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index f93583dff81..5c6c43017cf 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -43,7 +43,9 @@ /// `CString` implements a [`as_ptr`] method through the [`Deref`] /// trait. This method will give you a `*const c_char` which you can /// feed directly to extern functions that expect a nul-terminated -/// string, like C's `strdup()`. +/// string, like C's `strdup()`. Notice that [`as_ptr`] returns a +/// read-only pointer; if the C code writes to it, that causes +/// undefined behavior. /// /// # Extracting a slice of the whole C string /// @@ -61,7 +63,7 @@ /// /// Once you have the kind of slice you need (with or without a nul /// terminator), you can call the slice's own -/// [`as_ptr`][slice.as_ptr] method to get a raw pointer to pass to +/// [`as_ptr`][slice.as_ptr] method to get a read-only raw pointer to pass to /// extern functions. See the documentation for that function for a /// discussion on ensuring the lifetime of the raw pointer. /// @@ -1043,6 +1045,9 @@ pub fn from_bytes_with_nul(bytes: &[u8]) /// /// **WARNING** /// + /// The returned pointer is read-only; writing to it (including passing it + /// to C code that writes to it) causes undefined behavior. + /// /// It is your responsibility to make sure that the underlying memory is not /// freed too early. For example, the following code will cause undefined /// behavior when `ptr` is used inside the `unsafe` block: -- 2.44.0