diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-04-27 11:54:57 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-27 11:54:57 +0200 |
| commit | bd3af53489275cab11870d3cab915ed9ae9f0484 (patch) | |
| tree | 2dc829dd4260b003c11ead33b6808fac1a765883 | |
| parent | 9630242e5ee6b0c7eaaee7b9d9a1a5b567b66761 (diff) | |
| parent | bfdd947bbd5a2d242d0cbd728b3cbf2a30206b74 (diff) | |
| download | rust-bd3af53489275cab11870d3cab915ed9ae9f0484.tar.gz rust-bd3af53489275cab11870d3cab915ed9ae9f0484.zip | |
Rollup merge of #137714 - DiuDiu777:doc-fix, r=tgross35
Update safety documentation for `CString::from_ptr` and `str::from_boxed_utf8_unchecked`
## PR Description
This PR addresses missing safety documentation for two APIs:
**1. alloc::ffi::CStr::from_raw**
- `Alias`: The pointer must not be aliased (accessed via other pointers) during the reconstructed CString's lifetime.
- `Owning`: Calling this function twice on the same pointer and creating two objects with overlapping lifetimes, introduces two alive owners of the same memory. This may result in a double-free.
- `Dangling`: The prior documentation required the pointer to originate from CString::into_raw, but this constraint is incomplete. A validly sourced pointer can also cause undefined behavior (UB) if it becomes dangling. A simple Poc for this situation:
```
use std::ffi::CString;
use std::os::raw::c_char;
fn create_dangling() -> *mut c_char {
let local_ptr: *mut c_char = {
let valid_data = CString::new("valid").unwrap();
valid_data.into_raw()
};
unsafe {
let _x = CString::from_raw(local_ptr);
}
local_ptr
}
fn main() {
let dangling = create_dangling();
unsafe {let _y = CString::from_raw(dangling);} // Cause UB!
}
```
**2. alloc::str::from_boxed_utf8_unchecked**
- `ValidStr`: Bytes must contain a valid UTF-8 sequence.
| -rw-r--r-- | library/alloc/src/ffi/c_str.rs | 11 | ||||
| -rw-r--r-- | library/alloc/src/str.rs | 4 |
2 files changed, 12 insertions, 3 deletions
diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 2d05be51811..8b448a18402 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -351,9 +351,14 @@ impl CString { /// # Safety /// /// This should only ever be called with a pointer that was earlier - /// obtained by calling [`CString::into_raw`]. Other usage (e.g., trying to take - /// ownership of a string that was allocated by foreign code) is likely to lead - /// to undefined behavior or allocator corruption. + /// obtained by calling [`CString::into_raw`], and the memory it points to must not be accessed + /// through any other pointer during the lifetime of reconstructed `CString`. + /// Other usage (e.g., trying to take ownership of a string that was allocated by foreign code) + /// is likely to lead to undefined behavior or allocator corruption. + /// + /// This function does not validate ownership of the raw pointer's memory. + /// A double-free may occur if the function is called twice on the same raw pointer. + /// Additionally, the caller must ensure the pointer is not dangling. /// /// It should be noted that the length isn't just "recomputed," but that /// the recomputed length must match the original length from the diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 0664f2c3cf2..24c5d4c92f7 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -603,6 +603,10 @@ impl str { /// Converts a boxed slice of bytes to a boxed string slice without checking /// that the string contains valid UTF-8. /// +/// # Safety +/// +/// * The provided bytes must contain a valid UTF-8 sequence. +/// /// # Examples /// /// ``` |
