Skip to content

Commit 824ea6b

Browse files
authored
Rollup merge of #72963 - poliorcetics:cstring-from-raw, r=dtolnay
Cstring `from_raw` and `into_raw` safety precisions Fixes #48525. Fixes #68456. This issue had two points: - The one about `from_raw` has been addressed (I hope). - The other one, about `into_raw`, has only been partially fixed. About `into_raw`: the idea was to: > steer users away from using the pattern of CString::{into_raw,from_raw} when interfacing with C APIs that may change the effective length of the string by writing interior NULs or erasing the final NUL I tried making a `Vec<c_char>` like suggested but my current solution feels very unsafe and *hacky* to me (most notably the type cast), I included it here to make it available for discussion: ```rust fn main() { use std::os::raw::c_char; let v = String::from("abc") .bytes() // From u8 to i8, // I feel like it will be a problem for values of u8 > 255 .map(|c| c as c_char) .collect::<Vec<_>>(); dbg!(v); } ```
2 parents 13815e4 + 87abe17 commit 824ea6b

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

src/libstd/ffi/c_str.rs

+11
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,12 @@ impl CString {
395395
/// ownership of a string that was allocated by foreign code) is likely to lead
396396
/// to undefined behavior or allocator corruption.
397397
///
398+
/// It should be noted that the length isn't just "recomputed," but that
399+
/// the recomputed length must match the original length from the
400+
/// [`into_raw`] call. This means the [`into_raw`]/`from_raw` methods
401+
/// should not be used when passing the string to C functions that can
402+
/// modify the string's length.
403+
///
398404
/// > **Note:** If you need to borrow a string that was allocated by
399405
/// > foreign code, use [`CStr`]. If you need to take ownership of
400406
/// > a string that was allocated by foreign code, you will need to
@@ -440,6 +446,11 @@ impl CString {
440446
///
441447
/// Failure to call [`from_raw`] will lead to a memory leak.
442448
///
449+
/// The C side must **not** modify the length of the string (by writing a
450+
/// `NULL` somewhere inside the string or removing the final one) before
451+
/// it makes it back into Rust using [`from_raw`]. See the safety section
452+
/// in [`from_raw`].
453+
///
443454
/// [`from_raw`]: #method.from_raw
444455
///
445456
/// # Examples

0 commit comments

Comments
 (0)