alloc/ffi/
c_str.rs

1//! [`CString`] and its related types.
2
3use core::borrow::Borrow;
4use core::ffi::{CStr, c_char};
5use core::num::NonZero;
6use core::slice::memchr;
7use core::str::{self, FromStr, Utf8Error};
8use core::{fmt, mem, ops, ptr, slice};
9
10use crate::borrow::{Cow, ToOwned};
11use crate::boxed::Box;
12use crate::rc::Rc;
13use crate::string::String;
14#[cfg(target_has_atomic = "ptr")]
15use crate::sync::Arc;
16use crate::vec::Vec;
17
18/// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the
19/// middle.
20///
21/// This type serves the purpose of being able to safely generate a
22/// C-compatible string from a Rust byte slice or vector. An instance of this
23/// type is a static guarantee that the underlying bytes contain no interior 0
24/// bytes ("nul characters") and that the final byte is 0 ("nul terminator").
25///
26/// `CString` is to <code>&[CStr]</code> as [`String`] is to <code>&[str]</code>: the former
27/// in each pair are owned strings; the latter are borrowed
28/// references.
29///
30/// # Creating a `CString`
31///
32/// A `CString` is created from either a byte slice or a byte vector,
33/// or anything that implements <code>[Into]<[Vec]<[u8]>></code> (for
34/// example, you can build a `CString` straight out of a [`String`] or
35/// a <code>&[str]</code>, since both implement that trait).
36/// You can create a `CString` from a literal with `CString::from(c"Text")`.
37///
38/// The [`CString::new`] method will actually check that the provided <code>&[[u8]]</code>
39/// does not have 0 bytes in the middle, and return an error if it
40/// finds one.
41///
42/// # Extracting a raw pointer to the whole C string
43///
44/// `CString` implements an [`as_ptr`][`CStr::as_ptr`] method through the [`Deref`]
45/// trait. This method will give you a `*const c_char` which you can
46/// feed directly to extern functions that expect a nul-terminated
47/// string, like C's `strdup()`. Notice that [`as_ptr`][`CStr::as_ptr`] returns a
48/// read-only pointer; if the C code writes to it, that causes
49/// undefined behavior.
50///
51/// # Extracting a slice of the whole C string
52///
53/// Alternatively, you can obtain a <code>&[[u8]]</code> slice from a
54/// `CString` with the [`CString::as_bytes`] method. Slices produced in this
55/// way do *not* contain the trailing nul terminator. This is useful
56/// when you will be calling an extern function that takes a `*const
57/// u8` argument which is not necessarily nul-terminated, plus another
58/// argument with the length of the string — like C's `strndup()`.
59/// You can of course get the slice's length with its
60/// [`len`][slice::len] method.
61///
62/// If you need a <code>&[[u8]]</code> slice *with* the nul terminator, you
63/// can use [`CString::as_bytes_with_nul`] instead.
64///
65/// Once you have the kind of slice you need (with or without a nul
66/// terminator), you can call the slice's own
67/// [`as_ptr`][slice::as_ptr] method to get a read-only raw pointer to pass to
68/// extern functions. See the documentation for that function for a
69/// discussion on ensuring the lifetime of the raw pointer.
70///
71/// [str]: prim@str "str"
72/// [`Deref`]: ops::Deref
73///
74/// # Examples
75///
76/// ```ignore (extern-declaration)
77/// # fn main() {
78/// use std::ffi::CString;
79/// use std::os::raw::c_char;
80///
81/// extern "C" {
82///     fn my_printer(s: *const c_char);
83/// }
84///
85/// // We are certain that our string doesn't have 0 bytes in the middle,
86/// // so we can .expect()
87/// let c_to_print = CString::new("Hello, world!").expect("CString::new failed");
88/// unsafe {
89///     my_printer(c_to_print.as_ptr());
90/// }
91/// # }
92/// ```
93///
94/// # Safety
95///
96/// `CString` is intended for working with traditional C-style strings
97/// (a sequence of non-nul bytes terminated by a single nul byte); the
98/// primary use case for these kinds of strings is interoperating with C-like
99/// code. Often you will need to transfer ownership to/from that external
100/// code. It is strongly recommended that you thoroughly read through the
101/// documentation of `CString` before use, as improper ownership management
102/// of `CString` instances can lead to invalid memory accesses, memory leaks,
103/// and other memory errors.
104#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
105#[rustc_diagnostic_item = "cstring_type"]
106#[stable(feature = "alloc_c_string", since = "1.64.0")]
107pub struct CString {
108    // Invariant 1: the slice ends with a zero byte and has a length of at least one.
109    // Invariant 2: the slice contains only one zero byte.
110    // Improper usage of unsafe function can break Invariant 2, but not Invariant 1.
111    inner: Box<[u8]>,
112}
113
114/// An error indicating that an interior nul byte was found.
115///
116/// While Rust strings may contain nul bytes in the middle, C strings
117/// can't, as that byte would effectively truncate the string.
118///
119/// This error is created by the [`new`][`CString::new`] method on
120/// [`CString`]. See its documentation for more.
121///
122/// # Examples
123///
124/// ```
125/// use std::ffi::{CString, NulError};
126///
127/// let _: NulError = CString::new(b"f\0oo".to_vec()).unwrap_err();
128/// ```
129#[derive(Clone, PartialEq, Eq, Debug)]
130#[stable(feature = "alloc_c_string", since = "1.64.0")]
131pub struct NulError(usize, Vec<u8>);
132
133#[derive(Clone, PartialEq, Eq, Debug)]
134enum FromBytesWithNulErrorKind {
135    InteriorNul(usize),
136    NotNulTerminated,
137}
138
139/// An error indicating that a nul byte was not in the expected position.
140///
141/// The vector used to create a [`CString`] must have one and only one nul byte,
142/// positioned at the end.
143///
144/// This error is created by the [`CString::from_vec_with_nul`] method.
145/// See its documentation for more.
146///
147/// # Examples
148///
149/// ```
150/// use std::ffi::{CString, FromVecWithNulError};
151///
152/// let _: FromVecWithNulError = CString::from_vec_with_nul(b"f\0oo".to_vec()).unwrap_err();
153/// ```
154#[derive(Clone, PartialEq, Eq, Debug)]
155#[stable(feature = "alloc_c_string", since = "1.64.0")]
156pub struct FromVecWithNulError {
157    error_kind: FromBytesWithNulErrorKind,
158    bytes: Vec<u8>,
159}
160
161#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
162impl FromVecWithNulError {
163    /// Returns a slice of [`u8`]s bytes that were attempted to convert to a [`CString`].
164    ///
165    /// # Examples
166    ///
167    /// Basic usage:
168    ///
169    /// ```
170    /// use std::ffi::CString;
171    ///
172    /// // Some invalid bytes in a vector
173    /// let bytes = b"f\0oo".to_vec();
174    ///
175    /// let value = CString::from_vec_with_nul(bytes.clone());
176    ///
177    /// assert_eq!(&bytes[..], value.unwrap_err().as_bytes());
178    /// ```
179    #[must_use]
180    #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
181    pub fn as_bytes(&self) -> &[u8] {
182        &self.bytes[..]
183    }
184
185    /// Returns the bytes that were attempted to convert to a [`CString`].
186    ///
187    /// This method is carefully constructed to avoid allocation. It will
188    /// consume the error, moving out the bytes, so that a copy of the bytes
189    /// does not need to be made.
190    ///
191    /// # Examples
192    ///
193    /// Basic usage:
194    ///
195    /// ```
196    /// use std::ffi::CString;
197    ///
198    /// // Some invalid bytes in a vector
199    /// let bytes = b"f\0oo".to_vec();
200    ///
201    /// let value = CString::from_vec_with_nul(bytes.clone());
202    ///
203    /// assert_eq!(bytes, value.unwrap_err().into_bytes());
204    /// ```
205    #[must_use = "`self` will be dropped if the result is not used"]
206    #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
207    pub fn into_bytes(self) -> Vec<u8> {
208        self.bytes
209    }
210}
211
212/// An error indicating invalid UTF-8 when converting a [`CString`] into a [`String`].
213///
214/// `CString` is just a wrapper over a buffer of bytes with a nul terminator;
215/// [`CString::into_string`] performs UTF-8 validation on those bytes and may
216/// return this error.
217///
218/// This `struct` is created by [`CString::into_string()`]. See
219/// its documentation for more.
220#[derive(Clone, PartialEq, Eq, Debug)]
221#[stable(feature = "alloc_c_string", since = "1.64.0")]
222pub struct IntoStringError {
223    inner: CString,
224    error: Utf8Error,
225}
226
227impl CString {
228    /// Creates a new C-compatible string from a container of bytes.
229    ///
230    /// This function will consume the provided data and use the
231    /// underlying bytes to construct a new string, ensuring that
232    /// there is a trailing 0 byte. This trailing 0 byte will be
233    /// appended by this function; the provided data should *not*
234    /// contain any 0 bytes in it.
235    ///
236    /// # Examples
237    ///
238    /// ```ignore (extern-declaration)
239    /// use std::ffi::CString;
240    /// use std::os::raw::c_char;
241    ///
242    /// extern "C" { fn puts(s: *const c_char); }
243    ///
244    /// let to_print = CString::new("Hello!").expect("CString::new failed");
245    /// unsafe {
246    ///     puts(to_print.as_ptr());
247    /// }
248    /// ```
249    ///
250    /// # Errors
251    ///
252    /// This function will return an error if the supplied bytes contain an
253    /// internal 0 byte. The [`NulError`] returned will contain the bytes as well as
254    /// the position of the nul byte.
255    #[stable(feature = "rust1", since = "1.0.0")]
256    pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
257        trait SpecNewImpl {
258            fn spec_new_impl(self) -> Result<CString, NulError>;
259        }
260
261        impl<T: Into<Vec<u8>>> SpecNewImpl for T {
262            default fn spec_new_impl(self) -> Result<CString, NulError> {
263                let bytes: Vec<u8> = self.into();
264                match memchr::memchr(0, &bytes) {
265                    Some(i) => Err(NulError(i, bytes)),
266                    None => Ok(unsafe { CString::_from_vec_unchecked(bytes) }),
267                }
268            }
269        }
270
271        // Specialization for avoiding reallocation
272        #[inline(always)] // Without that it is not inlined into specializations
273        fn spec_new_impl_bytes(bytes: &[u8]) -> Result<CString, NulError> {
274            // We cannot have such large slice that we would overflow here
275            // but using `checked_add` allows LLVM to assume that capacity never overflows
276            // and generate twice shorter code.
277            // `saturating_add` doesn't help for some reason.
278            let capacity = bytes.len().checked_add(1).unwrap();
279
280            // Allocate before validation to avoid duplication of allocation code.
281            // We still need to allocate and copy memory even if we get an error.
282            let mut buffer = Vec::with_capacity(capacity);
283            buffer.extend(bytes);
284
285            // Check memory of self instead of new buffer.
286            // This allows better optimizations if lto enabled.
287            match memchr::memchr(0, bytes) {
288                Some(i) => Err(NulError(i, buffer)),
289                None => Ok(unsafe { CString::_from_vec_unchecked(buffer) }),
290            }
291        }
292
293        impl SpecNewImpl for &'_ [u8] {
294            fn spec_new_impl(self) -> Result<CString, NulError> {
295                spec_new_impl_bytes(self)
296            }
297        }
298
299        impl SpecNewImpl for &'_ str {
300            fn spec_new_impl(self) -> Result<CString, NulError> {
301                spec_new_impl_bytes(self.as_bytes())
302            }
303        }
304
305        impl SpecNewImpl for &'_ mut [u8] {
306            fn spec_new_impl(self) -> Result<CString, NulError> {
307                spec_new_impl_bytes(self)
308            }
309        }
310
311        t.spec_new_impl()
312    }
313
314    /// Creates a C-compatible string by consuming a byte vector,
315    /// without checking for interior 0 bytes.
316    ///
317    /// Trailing 0 byte will be appended by this function.
318    ///
319    /// This method is equivalent to [`CString::new`] except that no runtime
320    /// assertion is made that `v` contains no 0 bytes, and it requires an
321    /// actual byte vector, not anything that can be converted to one with Into.
322    ///
323    /// # Examples
324    ///
325    /// ```
326    /// use std::ffi::CString;
327    ///
328    /// let raw = b"foo".to_vec();
329    /// unsafe {
330    ///     let c_string = CString::from_vec_unchecked(raw);
331    /// }
332    /// ```
333    #[must_use]
334    #[stable(feature = "rust1", since = "1.0.0")]
335    pub unsafe fn from_vec_unchecked(v: Vec<u8>) -> Self {
336        debug_assert!(memchr::memchr(0, &v).is_none());
337        unsafe { Self::_from_vec_unchecked(v) }
338    }
339
340    unsafe fn _from_vec_unchecked(mut v: Vec<u8>) -> Self {
341        v.reserve_exact(1);
342        v.push(0);
343        Self { inner: v.into_boxed_slice() }
344    }
345
346    /// Retakes ownership of a `CString` that was transferred to C via
347    /// [`CString::into_raw`].
348    ///
349    /// Additionally, the length of the string will be recalculated from the pointer.
350    ///
351    /// # Safety
352    ///
353    /// This should only ever be called with a pointer that was earlier
354    /// obtained by calling [`CString::into_raw`], and the memory it points to must not be accessed
355    /// through any other pointer during the lifetime of reconstructed `CString`.
356    /// Other usage (e.g., trying to take ownership of a string that was allocated by foreign code)
357    /// is likely to lead to undefined behavior or allocator corruption.
358    ///
359    /// This function does not validate ownership of the raw pointer's memory.
360    /// A double-free may occur if the function is called twice on the same raw pointer.
361    /// Additionally, the caller must ensure the pointer is not dangling.
362    ///
363    /// It should be noted that the length isn't just "recomputed," but that
364    /// the recomputed length must match the original length from the
365    /// [`CString::into_raw`] call. This means the [`CString::into_raw`]/`from_raw`
366    /// methods should not be used when passing the string to C functions that can
367    /// modify the string's length.
368    ///
369    /// > **Note:** If you need to borrow a string that was allocated by
370    /// > foreign code, use [`CStr`]. If you need to take ownership of
371    /// > a string that was allocated by foreign code, you will need to
372    /// > make your own provisions for freeing it appropriately, likely
373    /// > with the foreign code's API to do that.
374    ///
375    /// # Examples
376    ///
377    /// Creates a `CString`, pass ownership to an `extern` function (via raw pointer), then retake
378    /// ownership with `from_raw`:
379    ///
380    /// ```ignore (extern-declaration)
381    /// use std::ffi::CString;
382    /// use std::os::raw::c_char;
383    ///
384    /// extern "C" {
385    ///     fn some_extern_function(s: *mut c_char);
386    /// }
387    ///
388    /// let c_string = CString::from(c"Hello!");
389    /// let raw = c_string.into_raw();
390    /// unsafe {
391    ///     some_extern_function(raw);
392    ///     let c_string = CString::from_raw(raw);
393    /// }
394    /// ```
395    #[must_use = "call `drop(from_raw(ptr))` if you intend to drop the `CString`"]
396    #[stable(feature = "cstr_memory", since = "1.4.0")]
397    pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
398        // SAFETY: This is called with a pointer that was obtained from a call
399        // to `CString::into_raw` and the length has not been modified. As such,
400        // we know there is a NUL byte (and only one) at the end and that the
401        // information about the size of the allocation is correct on Rust's
402        // side.
403        unsafe {
404            unsafe extern "C" {
405                /// Provided by libc or compiler_builtins.
406                fn strlen(s: *const c_char) -> usize;
407            }
408            let len = strlen(ptr) + 1; // Including the NUL byte
409            let slice = slice::from_raw_parts_mut(ptr, len);
410            CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
411        }
412    }
413
414    /// Consumes the `CString` and transfers ownership of the string to a C caller.
415    ///
416    /// The pointer which this function returns must be returned to Rust and reconstituted using
417    /// [`CString::from_raw`] to be properly deallocated. Specifically, one
418    /// should *not* use the standard C `free()` function to deallocate
419    /// this string.
420    ///
421    /// Failure to call [`CString::from_raw`] will lead to a memory leak.
422    ///
423    /// The C side must **not** modify the length of the string (by writing a
424    /// nul byte somewhere inside the string or removing the final one) before
425    /// it makes it back into Rust using [`CString::from_raw`]. See the safety section
426    /// in [`CString::from_raw`].
427    ///
428    /// # Examples
429    ///
430    /// ```
431    /// use std::ffi::CString;
432    ///
433    /// let c_string = CString::from(c"foo");
434    ///
435    /// let ptr = c_string.into_raw();
436    ///
437    /// unsafe {
438    ///     assert_eq!(b'f', *ptr as u8);
439    ///     assert_eq!(b'o', *ptr.add(1) as u8);
440    ///     assert_eq!(b'o', *ptr.add(2) as u8);
441    ///     assert_eq!(b'\0', *ptr.add(3) as u8);
442    ///
443    ///     // retake pointer to free memory
444    ///     let _ = CString::from_raw(ptr);
445    /// }
446    /// ```
447    #[inline]
448    #[must_use = "`self` will be dropped if the result is not used"]
449    #[stable(feature = "cstr_memory", since = "1.4.0")]
450    pub fn into_raw(self) -> *mut c_char {
451        Box::into_raw(self.into_inner()) as *mut c_char
452    }
453
454    /// Converts the `CString` into a [`String`] if it contains valid UTF-8 data.
455    ///
456    /// On failure, ownership of the original `CString` is returned.
457    ///
458    /// # Examples
459    ///
460    /// ```
461    /// use std::ffi::CString;
462    ///
463    /// let valid_utf8 = vec![b'f', b'o', b'o'];
464    /// let cstring = CString::new(valid_utf8).expect("CString::new failed");
465    /// assert_eq!(cstring.into_string().expect("into_string() call failed"), "foo");
466    ///
467    /// let invalid_utf8 = vec![b'f', 0xff, b'o', b'o'];
468    /// let cstring = CString::new(invalid_utf8).expect("CString::new failed");
469    /// let err = cstring.into_string().err().expect("into_string().err() failed");
470    /// assert_eq!(err.utf8_error().valid_up_to(), 1);
471    /// ```
472    #[stable(feature = "cstring_into", since = "1.7.0")]
473    pub fn into_string(self) -> Result<String, IntoStringError> {
474        String::from_utf8(self.into_bytes()).map_err(|e| IntoStringError {
475            error: e.utf8_error(),
476            inner: unsafe { Self::_from_vec_unchecked(e.into_bytes()) },
477        })
478    }
479
480    /// Consumes the `CString` and returns the underlying byte buffer.
481    ///
482    /// The returned buffer does **not** contain the trailing nul
483    /// terminator, and it is guaranteed to not have any interior nul
484    /// bytes.
485    ///
486    /// # Examples
487    ///
488    /// ```
489    /// use std::ffi::CString;
490    ///
491    /// let c_string = CString::from(c"foo");
492    /// let bytes = c_string.into_bytes();
493    /// assert_eq!(bytes, vec![b'f', b'o', b'o']);
494    /// ```
495    #[must_use = "`self` will be dropped if the result is not used"]
496    #[stable(feature = "cstring_into", since = "1.7.0")]
497    pub fn into_bytes(self) -> Vec<u8> {
498        let mut vec = self.into_inner().into_vec();
499        let _nul = vec.pop();
500        debug_assert_eq!(_nul, Some(0u8));
501        vec
502    }
503
504    /// Equivalent to [`CString::into_bytes()`] except that the
505    /// returned vector includes the trailing nul terminator.
506    ///
507    /// # Examples
508    ///
509    /// ```
510    /// use std::ffi::CString;
511    ///
512    /// let c_string = CString::from(c"foo");
513    /// let bytes = c_string.into_bytes_with_nul();
514    /// assert_eq!(bytes, vec![b'f', b'o', b'o', b'\0']);
515    /// ```
516    #[must_use = "`self` will be dropped if the result is not used"]
517    #[stable(feature = "cstring_into", since = "1.7.0")]
518    pub fn into_bytes_with_nul(self) -> Vec<u8> {
519        self.into_inner().into_vec()
520    }
521
522    /// Returns the contents of this `CString` as a slice of bytes.
523    ///
524    /// The returned slice does **not** contain the trailing nul
525    /// terminator, and it is guaranteed to not have any interior nul
526    /// bytes. If you need the nul terminator, use
527    /// [`CString::as_bytes_with_nul`] instead.
528    ///
529    /// # Examples
530    ///
531    /// ```
532    /// use std::ffi::CString;
533    ///
534    /// let c_string = CString::from(c"foo");
535    /// let bytes = c_string.as_bytes();
536    /// assert_eq!(bytes, &[b'f', b'o', b'o']);
537    /// ```
538    #[inline]
539    #[must_use]
540    #[stable(feature = "rust1", since = "1.0.0")]
541    pub fn as_bytes(&self) -> &[u8] {
542        // SAFETY: CString has a length at least 1
543        unsafe { self.inner.get_unchecked(..self.inner.len() - 1) }
544    }
545
546    /// Equivalent to [`CString::as_bytes()`] except that the
547    /// returned slice includes the trailing nul terminator.
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// use std::ffi::CString;
553    ///
554    /// let c_string = CString::from(c"foo");
555    /// let bytes = c_string.as_bytes_with_nul();
556    /// assert_eq!(bytes, &[b'f', b'o', b'o', b'\0']);
557    /// ```
558    #[inline]
559    #[must_use]
560    #[stable(feature = "rust1", since = "1.0.0")]
561    pub fn as_bytes_with_nul(&self) -> &[u8] {
562        &self.inner
563    }
564
565    /// Extracts a [`CStr`] slice containing the entire string.
566    ///
567    /// # Examples
568    ///
569    /// ```
570    /// use std::ffi::{CString, CStr};
571    ///
572    /// let c_string = CString::from(c"foo");
573    /// let cstr = c_string.as_c_str();
574    /// assert_eq!(cstr,
575    ///            CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"));
576    /// ```
577    #[inline]
578    #[must_use]
579    #[stable(feature = "as_c_str", since = "1.20.0")]
580    #[rustc_diagnostic_item = "cstring_as_c_str"]
581    pub fn as_c_str(&self) -> &CStr {
582        unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) }
583    }
584
585    /// Converts this `CString` into a boxed [`CStr`].
586    ///
587    /// # Examples
588    ///
589    /// ```
590    /// let c_string = c"foo".to_owned();
591    /// let boxed = c_string.into_boxed_c_str();
592    /// assert_eq!(boxed.to_bytes_with_nul(), b"foo\0");
593    /// ```
594    #[must_use = "`self` will be dropped if the result is not used"]
595    #[stable(feature = "into_boxed_c_str", since = "1.20.0")]
596    pub fn into_boxed_c_str(self) -> Box<CStr> {
597        unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut CStr) }
598    }
599
600    /// Bypass "move out of struct which implements [`Drop`] trait" restriction.
601    #[inline]
602    fn into_inner(self) -> Box<[u8]> {
603        // Rationale: `mem::forget(self)` invalidates the previous call to `ptr::read(&self.inner)`
604        // so we use `ManuallyDrop` to ensure `self` is not dropped.
605        // Then we can return the box directly without invalidating it.
606        // See https://github.com/rust-lang/rust/issues/62553.
607        let this = mem::ManuallyDrop::new(self);
608        unsafe { ptr::read(&this.inner) }
609    }
610
611    /// Converts a <code>[Vec]<[u8]></code> to a [`CString`] without checking the
612    /// invariants on the given [`Vec`].
613    ///
614    /// # Safety
615    ///
616    /// The given [`Vec`] **must** have one nul byte as its last element.
617    /// This means it cannot be empty nor have any other nul byte anywhere else.
618    ///
619    /// # Example
620    ///
621    /// ```
622    /// use std::ffi::CString;
623    /// assert_eq!(
624    ///     unsafe { CString::from_vec_with_nul_unchecked(b"abc\0".to_vec()) },
625    ///     unsafe { CString::from_vec_unchecked(b"abc".to_vec()) }
626    /// );
627    /// ```
628    #[must_use]
629    #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
630    pub unsafe fn from_vec_with_nul_unchecked(v: Vec<u8>) -> Self {
631        debug_assert!(memchr::memchr(0, &v).unwrap() + 1 == v.len());
632        unsafe { Self::_from_vec_with_nul_unchecked(v) }
633    }
634
635    unsafe fn _from_vec_with_nul_unchecked(v: Vec<u8>) -> Self {
636        Self { inner: v.into_boxed_slice() }
637    }
638
639    /// Attempts to converts a <code>[Vec]<[u8]></code> to a [`CString`].
640    ///
641    /// Runtime checks are present to ensure there is only one nul byte in the
642    /// [`Vec`], its last element.
643    ///
644    /// # Errors
645    ///
646    /// If a nul byte is present and not the last element or no nul bytes
647    /// is present, an error will be returned.
648    ///
649    /// # Examples
650    ///
651    /// A successful conversion will produce the same result as [`CString::new`]
652    /// when called without the ending nul byte.
653    ///
654    /// ```
655    /// use std::ffi::CString;
656    /// assert_eq!(
657    ///     CString::from_vec_with_nul(b"abc\0".to_vec())
658    ///         .expect("CString::from_vec_with_nul failed"),
659    ///     c"abc".to_owned()
660    /// );
661    /// ```
662    ///
663    /// An incorrectly formatted [`Vec`] will produce an error.
664    ///
665    /// ```
666    /// use std::ffi::{CString, FromVecWithNulError};
667    /// // Interior nul byte
668    /// let _: FromVecWithNulError = CString::from_vec_with_nul(b"a\0bc".to_vec()).unwrap_err();
669    /// // No nul byte
670    /// let _: FromVecWithNulError = CString::from_vec_with_nul(b"abc".to_vec()).unwrap_err();
671    /// ```
672    #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
673    pub fn from_vec_with_nul(v: Vec<u8>) -> Result<Self, FromVecWithNulError> {
674        let nul_pos = memchr::memchr(0, &v);
675        match nul_pos {
676            Some(nul_pos) if nul_pos + 1 == v.len() => {
677                // SAFETY: We know there is only one nul byte, at the end
678                // of the vec.
679                Ok(unsafe { Self::_from_vec_with_nul_unchecked(v) })
680            }
681            Some(nul_pos) => Err(FromVecWithNulError {
682                error_kind: FromBytesWithNulErrorKind::InteriorNul(nul_pos),
683                bytes: v,
684            }),
685            None => Err(FromVecWithNulError {
686                error_kind: FromBytesWithNulErrorKind::NotNulTerminated,
687                bytes: v,
688            }),
689        }
690    }
691}
692
693// Turns this `CString` into an empty string to prevent
694// memory-unsafe code from working by accident. Inline
695// to prevent LLVM from optimizing it away in debug builds.
696#[stable(feature = "cstring_drop", since = "1.13.0")]
697#[rustc_insignificant_dtor]
698impl Drop for CString {
699    #[inline]
700    fn drop(&mut self) {
701        unsafe {
702            *self.inner.get_unchecked_mut(0) = 0;
703        }
704    }
705}
706
707#[stable(feature = "rust1", since = "1.0.0")]
708impl ops::Deref for CString {
709    type Target = CStr;
710
711    #[inline]
712    fn deref(&self) -> &CStr {
713        self.as_c_str()
714    }
715}
716
717#[stable(feature = "rust1", since = "1.0.0")]
718impl fmt::Debug for CString {
719    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
720        fmt::Debug::fmt(self.as_c_str(), f)
721    }
722}
723
724#[stable(feature = "cstring_into", since = "1.7.0")]
725impl From<CString> for Vec<u8> {
726    /// Converts a [`CString`] into a <code>[Vec]<[u8]></code>.
727    ///
728    /// The conversion consumes the [`CString`], and removes the terminating NUL byte.
729    #[inline]
730    fn from(s: CString) -> Vec<u8> {
731        s.into_bytes()
732    }
733}
734
735#[stable(feature = "cstr_default", since = "1.10.0")]
736impl Default for CString {
737    /// Creates an empty `CString`.
738    fn default() -> CString {
739        let a: &CStr = Default::default();
740        a.to_owned()
741    }
742}
743
744#[stable(feature = "cstr_borrow", since = "1.3.0")]
745impl Borrow<CStr> for CString {
746    #[inline]
747    fn borrow(&self) -> &CStr {
748        self
749    }
750}
751
752#[stable(feature = "cstring_from_cow_cstr", since = "1.28.0")]
753impl<'a> From<Cow<'a, CStr>> for CString {
754    /// Converts a `Cow<'a, CStr>` into a `CString`, by copying the contents if they are
755    /// borrowed.
756    #[inline]
757    fn from(s: Cow<'a, CStr>) -> Self {
758        s.into_owned()
759    }
760}
761
762#[stable(feature = "box_from_c_str", since = "1.17.0")]
763impl From<&CStr> for Box<CStr> {
764    /// Converts a `&CStr` into a `Box<CStr>`,
765    /// by copying the contents into a newly allocated [`Box`].
766    fn from(s: &CStr) -> Box<CStr> {
767        let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul());
768        unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
769    }
770}
771
772#[stable(feature = "box_from_mut_slice", since = "1.84.0")]
773impl From<&mut CStr> for Box<CStr> {
774    /// Converts a `&mut CStr` into a `Box<CStr>`,
775    /// by copying the contents into a newly allocated [`Box`].
776    fn from(s: &mut CStr) -> Box<CStr> {
777        Self::from(&*s)
778    }
779}
780
781#[stable(feature = "box_from_cow", since = "1.45.0")]
782impl From<Cow<'_, CStr>> for Box<CStr> {
783    /// Converts a `Cow<'a, CStr>` into a `Box<CStr>`,
784    /// by copying the contents if they are borrowed.
785    #[inline]
786    fn from(cow: Cow<'_, CStr>) -> Box<CStr> {
787        match cow {
788            Cow::Borrowed(s) => Box::from(s),
789            Cow::Owned(s) => Box::from(s),
790        }
791    }
792}
793
794#[stable(feature = "c_string_from_box", since = "1.18.0")]
795impl From<Box<CStr>> for CString {
796    /// Converts a <code>[Box]<[CStr]></code> into a [`CString`] without copying or allocating.
797    #[inline]
798    fn from(s: Box<CStr>) -> CString {
799        let raw = Box::into_raw(s) as *mut [u8];
800        CString { inner: unsafe { Box::from_raw(raw) } }
801    }
802}
803
804#[stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0")]
805impl From<Vec<NonZero<u8>>> for CString {
806    /// Converts a <code>[Vec]<[NonZero]<[u8]>></code> into a [`CString`] without
807    /// copying nor checking for inner nul bytes.
808    #[inline]
809    fn from(v: Vec<NonZero<u8>>) -> CString {
810        unsafe {
811            // Transmute `Vec<NonZero<u8>>` to `Vec<u8>`.
812            let v: Vec<u8> = {
813                // SAFETY:
814                //   - transmuting between `NonZero<u8>` and `u8` is sound;
815                //   - `alloc::Layout<NonZero<u8>> == alloc::Layout<u8>`.
816                let (ptr, len, cap): (*mut NonZero<u8>, _, _) = Vec::into_raw_parts(v);
817                Vec::from_raw_parts(ptr.cast::<u8>(), len, cap)
818            };
819            // SAFETY: `v` cannot contain nul bytes, given the type-level
820            // invariant of `NonZero<u8>`.
821            Self::_from_vec_unchecked(v)
822        }
823    }
824}
825
826#[stable(feature = "c_string_from_str", since = "1.85.0")]
827impl FromStr for CString {
828    type Err = NulError;
829
830    /// Converts a string `s` into a [`CString`].
831    ///
832    /// This method is equivalent to [`CString::new`].
833    #[inline]
834    fn from_str(s: &str) -> Result<Self, Self::Err> {
835        Self::new(s)
836    }
837}
838
839#[stable(feature = "c_string_from_str", since = "1.85.0")]
840impl TryFrom<CString> for String {
841    type Error = IntoStringError;
842
843    /// Converts a [`CString`] into a [`String`] if it contains valid UTF-8 data.
844    ///
845    /// This method is equivalent to [`CString::into_string`].
846    #[inline]
847    fn try_from(value: CString) -> Result<Self, Self::Error> {
848        value.into_string()
849    }
850}
851
852#[stable(feature = "more_box_slice_clone", since = "1.29.0")]
853impl Clone for Box<CStr> {
854    #[inline]
855    fn clone(&self) -> Self {
856        (**self).into()
857    }
858}
859
860#[stable(feature = "box_from_c_string", since = "1.20.0")]
861impl From<CString> for Box<CStr> {
862    /// Converts a [`CString`] into a <code>[Box]<[CStr]></code> without copying or allocating.
863    #[inline]
864    fn from(s: CString) -> Box<CStr> {
865        s.into_boxed_c_str()
866    }
867}
868
869#[stable(feature = "cow_from_cstr", since = "1.28.0")]
870impl<'a> From<CString> for Cow<'a, CStr> {
871    /// Converts a [`CString`] into an owned [`Cow`] without copying or allocating.
872    #[inline]
873    fn from(s: CString) -> Cow<'a, CStr> {
874        Cow::Owned(s)
875    }
876}
877
878#[stable(feature = "cow_from_cstr", since = "1.28.0")]
879impl<'a> From<&'a CStr> for Cow<'a, CStr> {
880    /// Converts a [`CStr`] into a borrowed [`Cow`] without copying or allocating.
881    #[inline]
882    fn from(s: &'a CStr) -> Cow<'a, CStr> {
883        Cow::Borrowed(s)
884    }
885}
886
887#[stable(feature = "cow_from_cstr", since = "1.28.0")]
888impl<'a> From<&'a CString> for Cow<'a, CStr> {
889    /// Converts a `&`[`CString`] into a borrowed [`Cow`] without copying or allocating.
890    #[inline]
891    fn from(s: &'a CString) -> Cow<'a, CStr> {
892        Cow::Borrowed(s.as_c_str())
893    }
894}
895
896#[cfg(target_has_atomic = "ptr")]
897#[stable(feature = "shared_from_slice2", since = "1.24.0")]
898impl From<CString> for Arc<CStr> {
899    /// Converts a [`CString`] into an <code>[Arc]<[CStr]></code> by moving the [`CString`]
900    /// data into a new [`Arc`] buffer.
901    #[inline]
902    fn from(s: CString) -> Arc<CStr> {
903        let arc: Arc<[u8]> = Arc::from(s.into_inner());
904        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) }
905    }
906}
907
908#[cfg(target_has_atomic = "ptr")]
909#[stable(feature = "shared_from_slice2", since = "1.24.0")]
910impl From<&CStr> for Arc<CStr> {
911    /// Converts a `&CStr` into a `Arc<CStr>`,
912    /// by copying the contents into a newly allocated [`Arc`].
913    #[inline]
914    fn from(s: &CStr) -> Arc<CStr> {
915        let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul());
916        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) }
917    }
918}
919
920#[cfg(target_has_atomic = "ptr")]
921#[stable(feature = "shared_from_mut_slice", since = "1.84.0")]
922impl From<&mut CStr> for Arc<CStr> {
923    /// Converts a `&mut CStr` into a `Arc<CStr>`,
924    /// by copying the contents into a newly allocated [`Arc`].
925    #[inline]
926    fn from(s: &mut CStr) -> Arc<CStr> {
927        Arc::from(&*s)
928    }
929}
930
931#[stable(feature = "shared_from_slice2", since = "1.24.0")]
932impl From<CString> for Rc<CStr> {
933    /// Converts a [`CString`] into an <code>[Rc]<[CStr]></code> by moving the [`CString`]
934    /// data into a new [`Rc`] buffer.
935    #[inline]
936    fn from(s: CString) -> Rc<CStr> {
937        let rc: Rc<[u8]> = Rc::from(s.into_inner());
938        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) }
939    }
940}
941
942#[stable(feature = "shared_from_slice2", since = "1.24.0")]
943impl From<&CStr> for Rc<CStr> {
944    /// Converts a `&CStr` into a `Rc<CStr>`,
945    /// by copying the contents into a newly allocated [`Rc`].
946    #[inline]
947    fn from(s: &CStr) -> Rc<CStr> {
948        let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul());
949        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) }
950    }
951}
952
953#[stable(feature = "shared_from_mut_slice", since = "1.84.0")]
954impl From<&mut CStr> for Rc<CStr> {
955    /// Converts a `&mut CStr` into a `Rc<CStr>`,
956    /// by copying the contents into a newly allocated [`Rc`].
957    #[inline]
958    fn from(s: &mut CStr) -> Rc<CStr> {
959        Rc::from(&*s)
960    }
961}
962
963#[cfg(not(no_global_oom_handling))]
964#[stable(feature = "more_rc_default_impls", since = "1.80.0")]
965impl Default for Rc<CStr> {
966    /// Creates an empty CStr inside an Rc
967    ///
968    /// This may or may not share an allocation with other Rcs on the same thread.
969    #[inline]
970    fn default() -> Self {
971        let rc = Rc::<[u8]>::from(*b"\0");
972        // `[u8]` has the same layout as `CStr`, and it is `NUL` terminated.
973        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) }
974    }
975}
976
977#[stable(feature = "default_box_extra", since = "1.17.0")]
978impl Default for Box<CStr> {
979    fn default() -> Box<CStr> {
980        let boxed: Box<[u8]> = Box::from([0]);
981        unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
982    }
983}
984
985impl NulError {
986    /// Returns the position of the nul byte in the slice that caused
987    /// [`CString::new`] to fail.
988    ///
989    /// # Examples
990    ///
991    /// ```
992    /// use std::ffi::CString;
993    ///
994    /// let nul_error = CString::new("foo\0bar").unwrap_err();
995    /// assert_eq!(nul_error.nul_position(), 3);
996    ///
997    /// let nul_error = CString::new("foo bar\0").unwrap_err();
998    /// assert_eq!(nul_error.nul_position(), 7);
999    /// ```
1000    #[must_use]
1001    #[stable(feature = "rust1", since = "1.0.0")]
1002    pub fn nul_position(&self) -> usize {
1003        self.0
1004    }
1005
1006    /// Consumes this error, returning the underlying vector of bytes which
1007    /// generated the error in the first place.
1008    ///
1009    /// # Examples
1010    ///
1011    /// ```
1012    /// use std::ffi::CString;
1013    ///
1014    /// let nul_error = CString::new("foo\0bar").unwrap_err();
1015    /// assert_eq!(nul_error.into_vec(), b"foo\0bar");
1016    /// ```
1017    #[must_use = "`self` will be dropped if the result is not used"]
1018    #[stable(feature = "rust1", since = "1.0.0")]
1019    pub fn into_vec(self) -> Vec<u8> {
1020        self.1
1021    }
1022}
1023
1024#[stable(feature = "rust1", since = "1.0.0")]
1025impl fmt::Display for NulError {
1026    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1027        write!(f, "nul byte found in provided data at position: {}", self.0)
1028    }
1029}
1030
1031#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
1032impl fmt::Display for FromVecWithNulError {
1033    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1034        match self.error_kind {
1035            FromBytesWithNulErrorKind::InteriorNul(pos) => {
1036                write!(f, "data provided contains an interior nul byte at pos {pos}")
1037            }
1038            FromBytesWithNulErrorKind::NotNulTerminated => {
1039                write!(f, "data provided is not nul terminated")
1040            }
1041        }
1042    }
1043}
1044
1045impl IntoStringError {
1046    /// Consumes this error, returning original [`CString`] which generated the
1047    /// error.
1048    #[must_use = "`self` will be dropped if the result is not used"]
1049    #[stable(feature = "cstring_into", since = "1.7.0")]
1050    pub fn into_cstring(self) -> CString {
1051        self.inner
1052    }
1053
1054    /// Access the underlying UTF-8 error that was the cause of this error.
1055    #[must_use]
1056    #[stable(feature = "cstring_into", since = "1.7.0")]
1057    pub fn utf8_error(&self) -> Utf8Error {
1058        self.error
1059    }
1060}
1061
1062impl IntoStringError {
1063    fn description(&self) -> &str {
1064        "C string contained non-utf8 bytes"
1065    }
1066}
1067
1068#[stable(feature = "cstring_into", since = "1.7.0")]
1069impl fmt::Display for IntoStringError {
1070    #[allow(deprecated, deprecated_in_future)]
1071    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1072        self.description().fmt(f)
1073    }
1074}
1075
1076#[stable(feature = "cstr_borrow", since = "1.3.0")]
1077impl ToOwned for CStr {
1078    type Owned = CString;
1079
1080    fn to_owned(&self) -> CString {
1081        CString { inner: self.to_bytes_with_nul().into() }
1082    }
1083
1084    fn clone_into(&self, target: &mut CString) {
1085        let mut b = mem::take(&mut target.inner).into_vec();
1086        self.to_bytes_with_nul().clone_into(&mut b);
1087        target.inner = b.into_boxed_slice();
1088    }
1089}
1090
1091#[stable(feature = "cstring_asref", since = "1.7.0")]
1092impl From<&CStr> for CString {
1093    /// Converts a <code>&[CStr]</code> into a [`CString`]
1094    /// by copying the contents into a new allocation.
1095    fn from(s: &CStr) -> CString {
1096        s.to_owned()
1097    }
1098}
1099
1100#[stable(feature = "cstring_asref", since = "1.7.0")]
1101impl ops::Index<ops::RangeFull> for CString {
1102    type Output = CStr;
1103
1104    #[inline]
1105    fn index(&self, _index: ops::RangeFull) -> &CStr {
1106        self
1107    }
1108}
1109
1110#[stable(feature = "cstring_asref", since = "1.7.0")]
1111impl AsRef<CStr> for CString {
1112    #[inline]
1113    fn as_ref(&self) -> &CStr {
1114        self
1115    }
1116}
1117
1118impl CStr {
1119    /// Converts a `CStr` into a <code>[Cow]<[str]></code>.
1120    ///
1121    /// If the contents of the `CStr` are valid UTF-8 data, this
1122    /// function will return a <code>[Cow]::[Borrowed]\(&[str])</code>
1123    /// with the corresponding <code>&[str]</code> slice. Otherwise, it will
1124    /// replace any invalid UTF-8 sequences with
1125    /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a
1126    /// <code>[Cow]::[Owned]\([String])</code> with the result.
1127    ///
1128    /// [str]: prim@str "str"
1129    /// [Borrowed]: Cow::Borrowed
1130    /// [Owned]: Cow::Owned
1131    /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER "std::char::REPLACEMENT_CHARACTER"
1132    ///
1133    /// # Examples
1134    ///
1135    /// Calling `to_string_lossy` on a `CStr` containing valid UTF-8. The leading
1136    /// `c` on the string literal denotes a `CStr`.
1137    ///
1138    /// ```
1139    /// use std::borrow::Cow;
1140    ///
1141    /// assert_eq!(c"Hello World".to_string_lossy(), Cow::Borrowed("Hello World"));
1142    /// ```
1143    ///
1144    /// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8:
1145    ///
1146    /// ```
1147    /// use std::borrow::Cow;
1148    ///
1149    /// assert_eq!(
1150    ///     c"Hello \xF0\x90\x80World".to_string_lossy(),
1151    ///     Cow::Owned(String::from("Hello �World")) as Cow<'_, str>
1152    /// );
1153    /// ```
1154    #[rustc_allow_incoherent_impl]
1155    #[must_use = "this returns the result of the operation, \
1156                  without modifying the original"]
1157    #[stable(feature = "cstr_to_str", since = "1.4.0")]
1158    pub fn to_string_lossy(&self) -> Cow<'_, str> {
1159        String::from_utf8_lossy(self.to_bytes())
1160    }
1161
1162    /// Converts a <code>[Box]<[CStr]></code> into a [`CString`] without copying or allocating.
1163    ///
1164    /// # Examples
1165    ///
1166    /// ```
1167    /// use std::ffi::{CStr, CString};
1168    ///
1169    /// let boxed: Box<CStr> = Box::from(c"foo");
1170    /// let c_string: CString = c"foo".to_owned();
1171    ///
1172    /// assert_eq!(boxed.into_c_string(), c_string);
1173    /// ```
1174    #[rustc_allow_incoherent_impl]
1175    #[must_use = "`self` will be dropped if the result is not used"]
1176    #[stable(feature = "into_boxed_c_str", since = "1.20.0")]
1177    pub fn into_c_string(self: Box<Self>) -> CString {
1178        CString::from(self)
1179    }
1180}
1181
1182#[stable(feature = "rust1", since = "1.0.0")]
1183impl core::error::Error for NulError {
1184    #[allow(deprecated)]
1185    fn description(&self) -> &str {
1186        "nul byte found in data"
1187    }
1188}
1189
1190#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
1191impl core::error::Error for FromVecWithNulError {}
1192
1193#[stable(feature = "cstring_into", since = "1.7.0")]
1194impl core::error::Error for IntoStringError {
1195    #[allow(deprecated)]
1196    fn description(&self) -> &str {
1197        "C string contained non-utf8 bytes"
1198    }
1199
1200    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
1201        Some(&self.error)
1202    }
1203}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy