about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2020-06-08 09:55:30 +0200
committerGitHub <noreply@github.com>2020-06-08 09:55:30 +0200
commit824ea6bf2d883fd04ed826f1d09a20dc3ede11d0 (patch)
tree0011b35a9ecd651616be6a54cd2a2f3f3a83da13 /src/libstd
parent13815e4b35031ea86eefc2aea4515b753388bbb3 (diff)
parent87abe174c46bf10246369e63a36eccd6748b7dbe (diff)
downloadrust-824ea6bf2d883fd04ed826f1d09a20dc3ede11d0.tar.gz
rust-824ea6bf2d883fd04ed826f1d09a20dc3ede11d0.zip
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);
}
```
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ffi/c_str.rs11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 4bac9a4917d..b324b161896 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -395,6 +395,12 @@ impl CString {
     /// ownership of a string that was allocated by foreign code) is likely to lead
     /// to undefined behavior or allocator corruption.
     ///
+    /// It should be noted that the length isn't just "recomputed," but that
+    /// the recomputed length must match the original length from the
+    /// [`into_raw`] call. This means the [`into_raw`]/`from_raw` methods
+    /// should not be used when passing the string to C functions that can
+    /// modify the string's length.
+    ///
     /// > **Note:** If you need to borrow a string that was allocated by
     /// > foreign code, use [`CStr`]. If you need to take ownership of
     /// > a string that was allocated by foreign code, you will need to
@@ -440,6 +446,11 @@ impl CString {
     ///
     /// Failure to call [`from_raw`] will lead to a memory leak.
     ///
+    /// The C side must **not** modify the length of the string (by writing a
+    /// `NULL` somewhere inside the string or removing the final one) before
+    /// it makes it back into Rust using [`from_raw`]. See the safety section
+    /// in [`from_raw`].
+    ///
     /// [`from_raw`]: #method.from_raw
     ///
     /// # Examples