diff options
| author | Ralf Jung <post@ralfj.de> | 2020-06-08 09:55:30 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-08 09:55:30 +0200 |
| commit | 824ea6bf2d883fd04ed826f1d09a20dc3ede11d0 (patch) | |
| tree | 0011b35a9ecd651616be6a54cd2a2f3f3a83da13 /src/libstd | |
| parent | 13815e4b35031ea86eefc2aea4515b753388bbb3 (diff) | |
| parent | 87abe174c46bf10246369e63a36eccd6748b7dbe (diff) | |
| download | rust-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.rs | 11 |
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 |
