Skip to content

Commit 839d40c

Browse files
authored
Rollup merge of rust-lang#95948 - Nilstrieb:improve-cstr-safety-docs, r=RalfJung
Improve the safety docs for `CStr` Namely, the two functions `from_ptr` and `from_bytes_with_nul_unchecked`. Before, these functions didn't state the requirements clearly enough, and I was not immediately able to find them like for other functions. This doesn't change the content of the docs, but simply rewords them for clarity. note: I'm not entirely sure about the '`ptr` must be valid for reads of `u8`.', there might be room for improvement for this (and maybe for the other docs as well 😄)
2 parents 7d9d0c4 + f8e879e commit 839d40c

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

core/src/ffi/c_str.rs

+27-10
Original file line numberDiff line numberDiff line change
@@ -196,20 +196,32 @@ impl CStr {
196196
/// allows inspection and interoperation of non-owned C strings. The total
197197
/// size of the raw C string must be smaller than `isize::MAX` **bytes**
198198
/// in memory due to calling the `slice::from_raw_parts` function.
199-
/// This method is unsafe for a number of reasons:
200199
///
201-
/// * There is no guarantee to the validity of `ptr`.
202-
/// * The returned lifetime is not guaranteed to be the actual lifetime of
203-
/// `ptr`.
204-
/// * There is no guarantee that the memory pointed to by `ptr` contains a
205-
/// valid nul terminator byte at the end of the string.
206-
/// * It is not guaranteed that the memory pointed by `ptr` won't change
207-
/// before the `CStr` has been destroyed.
200+
/// # Safety
201+
///
202+
/// * The memory pointed to by `ptr` must contain a valid nul terminator at the
203+
/// end of the string.
204+
///
205+
/// * `ptr` must be [valid] for reads of bytes up to and including the null terminator.
206+
/// This means in particular:
207+
///
208+
/// * The entire memory range of this `CStr` must be contained within a single allocated object!
209+
/// * `ptr` must be non-null even for a zero-length cstr.
210+
///
211+
/// * The memory referenced by the returned `CStr` must not be mutated for
212+
/// the duration of lifetime `'a`.
208213
///
209214
/// > **Note**: This operation is intended to be a 0-cost cast but it is
210215
/// > currently implemented with an up-front calculation of the length of
211216
/// > the string. This is not guaranteed to always be the case.
212217
///
218+
/// # Caveat
219+
///
220+
/// The lifetime for the returned slice is inferred from its usage. To prevent accidental misuse,
221+
/// it's suggested to tie the lifetime to whichever source lifetime is safe in the context,
222+
/// such as by providing a helper function taking the lifetime of a host value for the slice,
223+
/// or by explicit annotation.
224+
///
213225
/// # Examples
214226
///
215227
/// ```ignore (extern-declaration)
@@ -227,6 +239,8 @@ impl CStr {
227239
/// }
228240
/// # }
229241
/// ```
242+
///
243+
/// [valid]: core::ptr#safety
230244
#[inline]
231245
#[must_use]
232246
#[stable(feature = "rust1", since = "1.0.0")]
@@ -349,8 +363,11 @@ impl CStr {
349363
/// Unsafely creates a C string wrapper from a byte slice.
350364
///
351365
/// This function will cast the provided `bytes` to a `CStr` wrapper without
352-
/// performing any sanity checks. The provided slice **must** be nul-terminated
353-
/// and not contain any interior nul bytes.
366+
/// performing any sanity checks.
367+
///
368+
/// # Safety
369+
/// The provided slice **must** be nul-terminated and not contain any interior
370+
/// nul bytes.
354371
///
355372
/// # Examples
356373
///

0 commit comments

Comments
 (0)