Skip to content

Clarify Vec::from_raw_parts safety examples #95427

Closed
@jmaargh

Description

@jmaargh

Looking at the documentation for Vec::from_raw_parts it says:

For example it is not safe to build a Vec<u8> from a pointer to a C char array with length size_t.

But it's not clear to me why this is not safe. My guess is that it's assumed to violate the "ptr needs to have been previously allocated via [String]/Vec<T> (at least, it's highly likely to be incorrect if it wasn't)." requirement. However, that's not necessarily the case, consider the following example (which I imagine is one of the main use-cases for this function):

let mut ascii_string_buffer = Vec::<u8>::with_capacity(512);
let ptr = ascii_string_buffer.as_mut_ptr();
let capacity = ascii_string_buffer.capacity();
let mut length = 0;
std::mem::forget(ascii_string_buffer);

unsafe {
    some_ffi_filling_the_buffer(ptr as _, &mut length);
    // error checking...
}

let ascii_string = unsafe { Vec::from_raw_parts(ptr, length, capacity) };

AFAICT this is all safe (assuming the length is checked to be valid after the FFI call). The same region of memory, allocated and deallocated by the correct allocator, with appropriate alignment, and all bit patterns are valid for u8.

Therefore, I suggest modifying the docs to read

For example it is not safe to build a Vec<u8> from an arbitrary pointer to a C char array with length size_t, the array must have been initially allocated by Vec or String for this to be safe.

I haven't checked, but it's possible other from_raw_parts docs could use similar clarifications. I'm happy to make a PR, but wanted to check that I wasn't mistaken first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions