rust-lang/rust

CStr from fixed c_char array

Opened this issue · 3 comments

Hi,

Often times I see a fixed array of C chars returned via FFI boundary which cannot be easily converted into CStr because:

  1. CStr::from_ptr() uses strlen() which can walk outside of boundaries of a fixed array
  2. CStr::from_bytes_until_nul(&[u8]) takes u8 slice.

Each time I stumble upon [c_char; N] it's always a struggle.

As such I think CStr should have an initializer from &[c_char] slice. This would work identical to CStr::from_ptr() except it wouldn't need to use strlen. It could flip the slice into &[u8] and then pass it into from_bytes_until_nul.

Any CStr is required to contain a nul terminator at the end. So assuming that all characters after the end of the string are nul bytes in your array, you could check that the last character in the array is a nul byte and use CStr::from_ptr in that case and return an error otherwise.

Note that [c_char; N] does not imply the null terminator is at N - 1 - such a faulty assumption has bitten libc++ in the past.

What you want is a from_bytes_until_nul variant accepts &[c_char], but you can't lose the O(n) complexity there.

Note that [c_char; N] does not imply the null terminator is at N - 1 - such a faulty assumption has bitten libc++ in the past.

What you want is a from_bytes_until_nul variant accepts &[c_char], but you can't lose the O(n) complexity there.

Yes. Often times the buffer has multiple trailing zeroes. from_bytes_until_nul is the right way to go about it. The missing bit is the awkward cast from i8 to u8.