1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT 2 // file at the top-level directory of this distribution and at 3 // http://rust-lang.org/COPYRIGHT. 4 // 5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 8 // option. This file may not be copied, modified, or distributed 9 // except according to those terms. 10 11 use alloc::{ 12 borrow::{Borrow, Cow, ToOwned}, 13 boxed::Box, 14 rc::Rc, 15 string::String, 16 sync::Arc, 17 vec::Vec, 18 }; 19 use core::{ 20 ascii, 21 cmp::Ordering, 22 fmt::{self, Write}, 23 mem, ops, ptr, slice, 24 str::{self, Utf8Error}, 25 }; 26 27 use crate::{header::string::strlen, platform::types::*}; 28 29 pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { 30 use crate::header::string; 31 32 let p = unsafe { 33 string::memchr( 34 haystack.as_ptr() as *const c_void, 35 needle as c_int, 36 haystack.len(), 37 ) 38 }; 39 if p.is_null() { 40 None 41 } else { 42 Some(p as usize - (haystack.as_ptr() as usize)) 43 } 44 } 45 46 /// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the 47 /// middle. 48 /// 49 /// This type serves the purpose of being able to safely generate a 50 /// C-compatible string from a Rust byte slice or vector. An instance of this 51 /// type is a static guarantee that the underlying bytes contain no interior 0 52 /// bytes ("nul characters") and that the final byte is 0 ("nul terminator"). 53 /// 54 /// `CString` is to [`CStr`] as [`String`] is to [`&str`]: the former 55 /// in each pair are owned strings; the latter are borrowed 56 /// references. 57 /// 58 /// # Creating a `CString` 59 /// 60 /// A `CString` is created from either a byte slice or a byte vector, 61 /// or anything that implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>` (for 62 /// example, you can build a `CString` straight out of a [`String`] or 63 /// a [`&str`], since both implement that trait). 64 /// 65 /// The [`new`] method will actually check that the provided `&[u8]` 66 /// does not have 0 bytes in the middle, and return an error if it 67 /// finds one. 68 /// 69 /// # Extracting a raw pointer to the whole C string 70 /// 71 /// `CString` implements a [`as_ptr`] method through the [`Deref`] 72 /// trait. This method will give you a `*const c_char` which you can 73 /// feed directly to extern functions that expect a nul-terminated 74 /// string, like C's `strdup()`. 75 /// 76 /// # Extracting a slice of the whole C string 77 /// 78 /// Alternatively, you can obtain a `&[`[`u8`]`]` slice from a 79 /// `CString` with the [`as_bytes`] method. Slices produced in this 80 /// way do *not* contain the trailing nul terminator. This is useful 81 /// when you will be calling an extern function that takes a `*const 82 /// u8` argument which is not necessarily nul-terminated, plus another 83 /// argument with the length of the string — like C's `strndup()`. 84 /// You can of course get the slice's length with its 85 /// [`len`][slice.len] method. 86 /// 87 /// If you need a `&[`[`u8`]`]` slice *with* the nul terminator, you 88 /// can use [`as_bytes_with_nul`] instead. 89 /// 90 /// Once you have the kind of slice you need (with or without a nul 91 /// terminator), you can call the slice's own 92 /// [`as_ptr`][slice.as_ptr] method to get a raw pointer to pass to 93 /// extern functions. See the documentation for that function for a 94 /// discussion on ensuring the lifetime of the raw pointer. 95 /// 96 /// [`Into`]: ../convert/trait.Into.html 97 /// [`Vec`]: ../vec/struct.Vec.html 98 /// [`String`]: ../string/struct.String.html 99 /// [`&str`]: ../primitive.str.html 100 /// [`u8`]: ../primitive.u8.html 101 /// [`new`]: #method.new 102 /// [`as_bytes`]: #method.as_bytes 103 /// [`as_bytes_with_nul`]: #method.as_bytes_with_nul 104 /// [`as_ptr`]: #method.as_ptr 105 /// [slice.as_ptr]: ../primitive.slice.html#method.as_ptr 106 /// [slice.len]: ../primitive.slice.html#method.len 107 /// [`Deref`]: ../ops/trait.Deref.html 108 /// [`CStr`]: struct.CStr.html 109 /// 110 /// # Examples 111 /// 112 /// ```ignore (extern-declaration) 113 /// # fn main() { 114 /// use std::ffi::CString; 115 /// use std::os::raw::c_char; 116 /// 117 /// extern { 118 /// fn my_printer(s: *const c_char); 119 /// } 120 /// 121 /// // We are certain that our string doesn't have 0 bytes in the middle, 122 /// // so we can .unwrap() 123 /// let c_to_print = CString::new("Hello, world!").unwrap(); 124 /// unsafe { 125 /// my_printer(c_to_print.as_ptr()); 126 /// } 127 /// # } 128 /// ``` 129 /// 130 /// # Safety 131 /// 132 /// `CString` is intended for working with traditional C-style strings 133 /// (a sequence of non-nul bytes terminated by a single nul byte); the 134 /// primary use case for these kinds of strings is interoperating with C-like 135 /// code. Often you will need to transfer ownership to/from that external 136 /// code. It is strongly recommended that you thoroughly read through the 137 /// documentation of `CString` before use, as improper ownership management 138 /// of `CString` instances can lead to invalid memory accesses, memory leaks, 139 /// and other memory errors. 140 141 #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] 142 pub struct CString { 143 // Invariant 1: the slice ends with a zero byte and has a length of at least one. 144 // Invariant 2: the slice contains only one zero byte. 145 // Improper usage of unsafe function can break Invariant 2, but not Invariant 1. 146 inner: Box<[u8]>, 147 } 148 149 /// Representation of a borrowed C string. 150 /// 151 /// This type represents a borrowed reference to a nul-terminated 152 /// array of bytes. It can be constructed safely from a `&[`[`u8`]`]` 153 /// slice, or unsafely from a raw `*const c_char`. It can then be 154 /// converted to a Rust [`&str`] by performing UTF-8 validation, or 155 /// into an owned [`CString`]. 156 /// 157 /// `CStr` is to [`CString`] as [`&str`] is to [`String`]: the former 158 /// in each pair are borrowed references; the latter are owned 159 /// strings. 160 /// 161 /// Note that this structure is **not** `repr(C)` and is not recommended to be 162 /// placed in the signatures of FFI functions. Instead, safe wrappers of FFI 163 /// functions may leverage the unsafe [`from_ptr`] constructor to provide a safe 164 /// interface to other consumers. 165 /// 166 /// # Examples 167 /// 168 /// Inspecting a foreign C string: 169 /// 170 /// ```ignore (extern-declaration) 171 /// use std::ffi::CStr; 172 /// use std::os::raw::c_char; 173 /// 174 /// extern { fn my_string() -> *const c_char; } 175 /// 176 /// unsafe { 177 /// let slice = CStr::from_ptr(my_string()); 178 /// println!("string buffer size without nul terminator: {}", slice.to_bytes().len()); 179 /// } 180 /// ``` 181 /// 182 /// Passing a Rust-originating C string: 183 /// 184 /// ```ignore (extern-declaration) 185 /// use std::ffi::{CString, CStr}; 186 /// use std::os::raw::c_char; 187 /// 188 /// fn work(data: &CStr) { 189 /// extern { fn work_with(data: *const c_char); } 190 /// 191 /// unsafe { work_with(data.as_ptr()) } 192 /// } 193 /// 194 /// let s = CString::new("data data data data").unwrap(); 195 /// work(&s); 196 /// ``` 197 /// 198 /// Converting a foreign C string into a Rust [`String`]: 199 /// 200 /// ```ignore (extern-declaration) 201 /// use std::ffi::CStr; 202 /// use std::os::raw::c_char; 203 /// 204 /// extern { fn my_string() -> *const c_char; } 205 /// 206 /// fn my_string_safe() -> String { 207 /// unsafe { 208 /// CStr::from_ptr(my_string()).to_string_lossy().into_owned() 209 /// } 210 /// } 211 /// 212 /// println!("string: {}", my_string_safe()); 213 /// ``` 214 /// 215 /// [`u8`]: ../primitive.u8.html 216 /// [`&str`]: ../primitive.str.html 217 /// [`String`]: ../string/struct.String.html 218 /// [`CString`]: struct.CString.html 219 /// [`from_ptr`]: #method.from_ptr 220 #[derive(Hash)] 221 pub struct CStr { 222 // FIXME: this should not be represented with a DST slice but rather with 223 // just a raw `c_char` along with some form of marker to make 224 // this an unsized type. Essentially `sizeof(&CStr)` should be the 225 // same as `sizeof(&c_char)` but `CStr` should be an unsized type. 226 inner: [c_char], 227 } 228 229 /// An error indicating that an interior nul byte was found. 230 /// 231 /// While Rust strings may contain nul bytes in the middle, C strings 232 /// can't, as that byte would effectively truncate the string. 233 /// 234 /// This error is created by the [`new`][`CString::new`] method on 235 /// [`CString`]. See its documentation for more. 236 /// 237 /// [`CString`]: struct.CString.html 238 /// [`CString::new`]: struct.CString.html#method.new 239 /// 240 /// # Examples 241 /// 242 /// ``` 243 /// use std::ffi::{CString, NulError}; 244 /// 245 /// let _: NulError = CString::new(b"f\0oo".to_vec()).unwrap_err(); 246 /// ``` 247 #[derive(Clone, PartialEq, Eq, Debug)] 248 pub struct NulError(usize, Vec<u8>); 249 250 /// An error indicating that a nul byte was not in the expected position. 251 /// 252 /// The slice used to create a [`CStr`] must have one and only one nul 253 /// byte at the end of the slice. 254 /// 255 /// This error is created by the 256 /// [`from_bytes_with_nul`][`CStr::from_bytes_with_nul`] method on 257 /// [`CStr`]. See its documentation for more. 258 /// 259 /// [`CStr`]: struct.CStr.html 260 /// [`CStr::from_bytes_with_nul`]: struct.CStr.html#method.from_bytes_with_nul 261 /// 262 /// # Examples 263 /// 264 /// ``` 265 /// use std::ffi::{CStr, FromBytesWithNulError}; 266 /// 267 /// let _: FromBytesWithNulError = CStr::from_bytes_with_nul(b"f\0oo").unwrap_err(); 268 /// ``` 269 #[derive(Clone, PartialEq, Eq, Debug)] 270 pub struct FromBytesWithNulError { 271 kind: FromBytesWithNulErrorKind, 272 } 273 274 #[derive(Clone, PartialEq, Eq, Debug)] 275 enum FromBytesWithNulErrorKind { 276 InteriorNul(usize), 277 NotNulTerminated, 278 } 279 280 impl FromBytesWithNulError { 281 fn interior_nul(pos: usize) -> FromBytesWithNulError { 282 FromBytesWithNulError { 283 kind: FromBytesWithNulErrorKind::InteriorNul(pos), 284 } 285 } 286 fn not_nul_terminated() -> FromBytesWithNulError { 287 FromBytesWithNulError { 288 kind: FromBytesWithNulErrorKind::NotNulTerminated, 289 } 290 } 291 292 fn description(&self) -> &str { 293 match self.kind { 294 FromBytesWithNulErrorKind::InteriorNul(..) => { 295 "data provided contains an interior nul byte" 296 } 297 FromBytesWithNulErrorKind::NotNulTerminated => "data provided is not nul terminated", 298 } 299 } 300 } 301 302 /// An error indicating invalid UTF-8 when converting a [`CString`] into a [`String`]. 303 /// 304 /// `CString` is just a wrapper over a buffer of bytes with a nul 305 /// terminator; [`into_string`][`CString::into_string`] performs UTF-8 306 /// validation on those bytes and may return this error. 307 /// 308 /// This `struct` is created by the 309 /// [`into_string`][`CString::into_string`] method on [`CString`]. See 310 /// its documentation for more. 311 /// 312 /// [`String`]: ../string/struct.String.html 313 /// [`CString`]: struct.CString.html 314 /// [`CString::into_string`]: struct.CString.html#method.into_string 315 #[derive(Clone, PartialEq, Eq, Debug)] 316 pub struct IntoStringError { 317 inner: CString, 318 error: Utf8Error, 319 } 320 321 impl CString { 322 /// Creates a new C-compatible string from a container of bytes. 323 /// 324 /// This function will consume the provided data and use the 325 /// underlying bytes to construct a new string, ensuring that 326 /// there is a trailing 0 byte. This trailing 0 byte will be 327 /// appended by this function; the provided data should *not* 328 /// contain any 0 bytes in it. 329 /// 330 /// # Examples 331 /// 332 /// ```ignore (extern-declaration) 333 /// use std::ffi::CString; 334 /// use std::os::raw::c_char; 335 /// 336 /// extern { fn puts(s: *const c_char); } 337 /// 338 /// let to_print = CString::new("Hello!").unwrap(); 339 /// unsafe { 340 /// puts(to_print.as_ptr()); 341 /// } 342 /// ``` 343 /// 344 /// # Errors 345 /// 346 /// This function will return an error if the supplied bytes contain an 347 /// internal 0 byte. The [`NulError`] returned will contain the bytes as well as 348 /// the position of the nul byte. 349 /// 350 /// [`NulError`]: struct.NulError.html 351 pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> { 352 Self::_new(t.into()) 353 } 354 355 fn _new(bytes: Vec<u8>) -> Result<CString, NulError> { 356 match memchr(0, &bytes) { 357 Some(i) => Err(NulError(i, bytes)), 358 None => Ok(unsafe { CString::from_vec_unchecked(bytes) }), 359 } 360 } 361 362 /// Creates a C-compatible string by consuming a byte vector, 363 /// without checking for interior 0 bytes. 364 /// 365 /// This method is equivalent to [`new`] except that no runtime assertion 366 /// is made that `v` contains no 0 bytes, and it requires an actual 367 /// byte vector, not anything that can be converted to one with Into. 368 /// 369 /// [`new`]: #method.new 370 /// 371 /// # Examples 372 /// 373 /// ``` 374 /// use std::ffi::CString; 375 /// 376 /// let raw = b"foo".to_vec(); 377 /// unsafe { 378 /// let c_string = CString::from_vec_unchecked(raw); 379 /// } 380 /// ``` 381 pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString { 382 v.reserve_exact(1); 383 v.push(0); 384 CString { 385 inner: v.into_boxed_slice(), 386 } 387 } 388 389 /// Retakes ownership of a `CString` that was transferred to C via [`into_raw`]. 390 /// 391 /// Additionally, the length of the string will be recalculated from the pointer. 392 /// 393 /// # Safety 394 /// 395 /// This should only ever be called with a pointer that was earlier 396 /// obtained by calling [`into_raw`] on a `CString`. Other usage (e.g. trying to take 397 /// ownership of a string that was allocated by foreign code) is likely to lead 398 /// to undefined behavior or allocator corruption. 399 /// 400 /// > **Note:** If you need to borrow a string that was allocated by 401 /// > foreign code, use [`CStr`]. If you need to take ownership of 402 /// > a string that was allocated by foreign code, you will need to 403 /// > make your own provisions for freeing it appropriately, likely 404 /// > with the foreign code's API to do that. 405 /// 406 /// [`into_raw`]: #method.into_raw 407 /// [`CStr`]: struct.CStr.html 408 /// 409 /// # Examples 410 /// 411 /// Create a `CString`, pass ownership to an `extern` function (via raw pointer), then retake 412 /// ownership with `from_raw`: 413 /// 414 /// ```ignore (extern-declaration) 415 /// use std::ffi::CString; 416 /// use std::os::raw::c_char; 417 /// 418 /// extern { 419 /// fn some_extern_function(s: *mut c_char); 420 /// } 421 /// 422 /// let c_string = CString::new("Hello!").unwrap(); 423 /// let raw = c_string.into_raw(); 424 /// unsafe { 425 /// some_extern_function(raw); 426 /// let c_string = CString::from_raw(raw); 427 /// } 428 /// ``` 429 pub unsafe fn from_raw(ptr: *mut c_char) -> CString { 430 let len = strlen(ptr) + 1; // Including the NUL byte 431 let slice = slice::from_raw_parts_mut(ptr, len as usize); 432 CString { 433 inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]), 434 } 435 } 436 437 /// Consumes the `CString` and transfers ownership of the string to a C caller. 438 /// 439 /// The pointer which this function returns must be returned to Rust and reconstituted using 440 /// [`from_raw`] to be properly deallocated. Specifically, one 441 /// should *not* use the standard C `free()` function to deallocate 442 /// this string. 443 /// 444 /// Failure to call [`from_raw`] will lead to a memory leak. 445 /// 446 /// [`from_raw`]: #method.from_raw 447 /// 448 /// # Examples 449 /// 450 /// ``` 451 /// use std::ffi::CString; 452 /// 453 /// let c_string = CString::new("foo").unwrap(); 454 /// 455 /// let ptr = c_string.into_raw(); 456 /// 457 /// unsafe { 458 /// assert_eq!(b'f', *ptr as u8); 459 /// assert_eq!(b'o', *ptr.offset(1) as u8); 460 /// assert_eq!(b'o', *ptr.offset(2) as u8); 461 /// assert_eq!(b'\0', *ptr.offset(3) as u8); 462 /// 463 /// // retake pointer to free memory 464 /// let _ = CString::from_raw(ptr); 465 /// } 466 /// ``` 467 #[inline] 468 pub fn into_raw(self) -> *mut c_char { 469 Box::into_raw(self.into_inner()) as *mut c_char 470 } 471 472 /// Converts the `CString` into a [`String`] if it contains valid UTF-8 data. 473 /// 474 /// On failure, ownership of the original `CString` is returned. 475 /// 476 /// [`String`]: ../string/struct.String.html 477 /// 478 /// # Examples 479 /// 480 /// ``` 481 /// use std::ffi::CString; 482 /// 483 /// let valid_utf8 = vec![b'f', b'o', b'o']; 484 /// let cstring = CString::new(valid_utf8).unwrap(); 485 /// assert_eq!(cstring.into_string().unwrap(), "foo"); 486 /// 487 /// let invalid_utf8 = vec![b'f', 0xff, b'o', b'o']; 488 /// let cstring = CString::new(invalid_utf8).unwrap(); 489 /// let err = cstring.into_string().err().unwrap(); 490 /// assert_eq!(err.utf8_error().valid_up_to(), 1); 491 /// ``` 492 493 pub fn into_string(self) -> Result<String, IntoStringError> { 494 String::from_utf8(self.into_bytes()).map_err(|e| IntoStringError { 495 error: e.utf8_error(), 496 inner: unsafe { CString::from_vec_unchecked(e.into_bytes()) }, 497 }) 498 } 499 500 /// Consumes the `CString` and returns the underlying byte buffer. 501 /// 502 /// The returned buffer does **not** contain the trailing nul 503 /// terminator, and it is guaranteed to not have any interior nul 504 /// bytes. 505 /// 506 /// # Examples 507 /// 508 /// ``` 509 /// use std::ffi::CString; 510 /// 511 /// let c_string = CString::new("foo").unwrap(); 512 /// let bytes = c_string.into_bytes(); 513 /// assert_eq!(bytes, vec![b'f', b'o', b'o']); 514 /// ``` 515 pub fn into_bytes(self) -> Vec<u8> { 516 let mut vec = self.into_inner().into_vec(); 517 let _nul = vec.pop(); 518 debug_assert_eq!(_nul, Some(0u8)); 519 vec 520 } 521 522 /// Equivalent to the [`into_bytes`] function except that the returned vector 523 /// includes the trailing nul terminator. 524 /// 525 /// [`into_bytes`]: #method.into_bytes 526 /// 527 /// # Examples 528 /// 529 /// ``` 530 /// use std::ffi::CString; 531 /// 532 /// let c_string = CString::new("foo").unwrap(); 533 /// let bytes = c_string.into_bytes_with_nul(); 534 /// assert_eq!(bytes, vec![b'f', b'o', b'o', b'\0']); 535 /// ``` 536 pub fn into_bytes_with_nul(self) -> Vec<u8> { 537 self.into_inner().into_vec() 538 } 539 540 /// Returns the contents of this `CString` as a slice of bytes. 541 /// 542 /// The returned slice does **not** contain the trailing nul 543 /// terminator, and it is guaranteed to not have any interior nul 544 /// bytes. If you need the nul terminator, use 545 /// [`as_bytes_with_nul`] instead. 546 /// 547 /// [`as_bytes_with_nul`]: #method.as_bytes_with_nul 548 /// 549 /// # Examples 550 /// 551 /// ``` 552 /// use std::ffi::CString; 553 /// 554 /// let c_string = CString::new("foo").unwrap(); 555 /// let bytes = c_string.as_bytes(); 556 /// assert_eq!(bytes, &[b'f', b'o', b'o']); 557 /// ``` 558 #[inline] 559 pub fn as_bytes(&self) -> &[u8] { 560 &self.inner[..self.inner.len() - 1] 561 } 562 563 /// Equivalent to the [`as_bytes`] function except that the returned slice 564 /// includes the trailing nul terminator. 565 /// 566 /// [`as_bytes`]: #method.as_bytes 567 /// 568 /// # Examples 569 /// 570 /// ``` 571 /// use std::ffi::CString; 572 /// 573 /// let c_string = CString::new("foo").unwrap(); 574 /// let bytes = c_string.as_bytes_with_nul(); 575 /// assert_eq!(bytes, &[b'f', b'o', b'o', b'\0']); 576 /// ``` 577 #[inline] 578 pub fn as_bytes_with_nul(&self) -> &[u8] { 579 &self.inner 580 } 581 582 /// Extracts a [`CStr`] slice containing the entire string. 583 /// 584 /// [`CStr`]: struct.CStr.html 585 /// 586 /// # Examples 587 /// 588 /// ``` 589 /// use std::ffi::{CString, CStr}; 590 /// 591 /// let c_string = CString::new(b"foo".to_vec()).unwrap(); 592 /// let c_str = c_string.as_c_str(); 593 /// assert_eq!(c_str, CStr::from_bytes_with_nul(b"foo\0").unwrap()); 594 /// ``` 595 #[inline] 596 pub fn as_c_str(&self) -> &CStr { 597 &*self 598 } 599 600 /// Converts this `CString` into a boxed [`CStr`]. 601 /// 602 /// [`CStr`]: struct.CStr.html 603 /// 604 /// # Examples 605 /// 606 /// ``` 607 /// use std::ffi::{CString, CStr}; 608 /// 609 /// let c_string = CString::new(b"foo".to_vec()).unwrap(); 610 /// let boxed = c_string.into_boxed_c_str(); 611 /// assert_eq!(&*boxed, CStr::from_bytes_with_nul(b"foo\0").unwrap()); 612 /// ``` 613 pub fn into_boxed_c_str(self) -> Box<CStr> { 614 unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut CStr) } 615 } 616 617 // Bypass "move out of struct which implements [`Drop`] trait" restriction. 618 /// 619 /// [`Drop`]: ../ops/trait.Drop.html 620 fn into_inner(self) -> Box<[u8]> { 621 unsafe { 622 let result = ptr::read(&self.inner); 623 mem::forget(self); 624 result 625 } 626 } 627 } 628 629 // Turns this `CString` into an empty string to prevent 630 // memory unsafe code from working by accident. Inline 631 // to prevent LLVM from optimizing it away in debug builds. 632 impl Drop for CString { 633 #[inline] 634 fn drop(&mut self) { 635 unsafe { 636 *self.inner.get_unchecked_mut(0) = 0; 637 } 638 } 639 } 640 641 impl ops::Deref for CString { 642 type Target = CStr; 643 644 #[inline] 645 fn deref(&self) -> &CStr { 646 unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) } 647 } 648 } 649 650 impl fmt::Debug for CString { 651 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 652 fmt::Debug::fmt(&**self, f) 653 } 654 } 655 656 impl From<CString> for Vec<u8> { 657 /// Converts a [`CString`] into a [`Vec`]`<u8>`. 658 /// 659 /// The conversion consumes the [`CString`], and removes the terminating NUL byte. 660 /// 661 /// [`Vec`]: ../vec/struct.Vec.html 662 /// [`CString`]: ../ffi/struct.CString.html 663 #[inline] 664 fn from(s: CString) -> Vec<u8> { 665 s.into_bytes() 666 } 667 } 668 669 impl fmt::Debug for CStr { 670 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 671 write!(f, "\"")?; 672 for byte in self 673 .to_bytes() 674 .iter() 675 .flat_map(|&b| ascii::escape_default(b)) 676 { 677 f.write_char(byte as char)?; 678 } 679 write!(f, "\"") 680 } 681 } 682 683 impl<'a> Default for &'a CStr { 684 fn default() -> &'a CStr { 685 const SLICE: &[c_char] = &[0]; 686 unsafe { CStr::from_ptr(SLICE.as_ptr()) } 687 } 688 } 689 690 impl Default for CString { 691 /// Creates an empty `CString`. 692 fn default() -> CString { 693 let a: &CStr = Default::default(); 694 a.to_owned() 695 } 696 } 697 698 impl Borrow<CStr> for CString { 699 #[inline] 700 fn borrow(&self) -> &CStr { 701 self 702 } 703 } 704 705 impl<'a> From<Cow<'a, CStr>> for CString { 706 #[inline] 707 fn from(s: Cow<'a, CStr>) -> Self { 708 s.into_owned() 709 } 710 } 711 712 impl<'a> From<&'a CStr> for Box<CStr> { 713 fn from(s: &'a CStr) -> Box<CStr> { 714 let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul()); 715 unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) } 716 } 717 } 718 719 impl From<Box<CStr>> for CString { 720 /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating. 721 /// 722 /// [`Box`]: ../boxed/struct.Box.html 723 /// [`CString`]: ../ffi/struct.CString.html 724 #[inline] 725 fn from(s: Box<CStr>) -> CString { 726 s.into_c_string() 727 } 728 } 729 730 impl Clone for Box<CStr> { 731 #[inline] 732 fn clone(&self) -> Self { 733 (**self).into() 734 } 735 } 736 737 impl From<CString> for Box<CStr> { 738 /// Converts a [`CString`] into a [`Box`]`<CStr>` without copying or allocating. 739 /// 740 /// [`CString`]: ../ffi/struct.CString.html 741 /// [`Box`]: ../boxed/struct.Box.html 742 #[inline] 743 fn from(s: CString) -> Box<CStr> { 744 s.into_boxed_c_str() 745 } 746 } 747 748 impl<'a> From<CString> for Cow<'a, CStr> { 749 #[inline] 750 fn from(s: CString) -> Cow<'a, CStr> { 751 Cow::Owned(s) 752 } 753 } 754 755 impl<'a> From<&'a CStr> for Cow<'a, CStr> { 756 #[inline] 757 fn from(s: &'a CStr) -> Cow<'a, CStr> { 758 Cow::Borrowed(s) 759 } 760 } 761 762 impl<'a> From<&'a CString> for Cow<'a, CStr> { 763 #[inline] 764 fn from(s: &'a CString) -> Cow<'a, CStr> { 765 Cow::Borrowed(s.as_c_str()) 766 } 767 } 768 769 impl From<CString> for Arc<CStr> { 770 /// Converts a [`CString`] into a [`Arc`]`<CStr>` without copying or allocating. 771 /// 772 /// [`CString`]: ../ffi/struct.CString.html 773 /// [`Arc`]: ../sync/struct.Arc.html 774 #[inline] 775 fn from(s: CString) -> Arc<CStr> { 776 let arc: Arc<[u8]> = Arc::from(s.into_inner()); 777 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) } 778 } 779 } 780 781 impl<'a> From<&'a CStr> for Arc<CStr> { 782 #[inline] 783 fn from(s: &CStr) -> Arc<CStr> { 784 let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul()); 785 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) } 786 } 787 } 788 789 impl From<CString> for Rc<CStr> { 790 /// Converts a [`CString`] into a [`Rc`]`<CStr>` without copying or allocating. 791 /// 792 /// [`CString`]: ../ffi/struct.CString.html 793 /// [`Rc`]: ../rc/struct.Rc.html 794 #[inline] 795 fn from(s: CString) -> Rc<CStr> { 796 let rc: Rc<[u8]> = Rc::from(s.into_inner()); 797 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) } 798 } 799 } 800 801 impl<'a> From<&'a CStr> for Rc<CStr> { 802 #[inline] 803 fn from(s: &CStr) -> Rc<CStr> { 804 let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul()); 805 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) } 806 } 807 } 808 809 impl Default for Box<CStr> { 810 fn default() -> Box<CStr> { 811 let boxed: Box<[u8]> = Box::from([0]); 812 unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) } 813 } 814 } 815 816 impl NulError { 817 /// Returns the position of the nul byte in the slice that caused 818 /// [`CString::new`] to fail. 819 /// 820 /// [`CString::new`]: struct.CString.html#method.new 821 /// 822 /// # Examples 823 /// 824 /// ``` 825 /// use std::ffi::CString; 826 /// 827 /// let nul_error = CString::new("foo\0bar").unwrap_err(); 828 /// assert_eq!(nul_error.nul_position(), 3); 829 /// 830 /// let nul_error = CString::new("foo bar\0").unwrap_err(); 831 /// assert_eq!(nul_error.nul_position(), 7); 832 /// ``` 833 pub fn nul_position(&self) -> usize { 834 self.0 835 } 836 837 /// Consumes this error, returning the underlying vector of bytes which 838 /// generated the error in the first place. 839 /// 840 /// # Examples 841 /// 842 /// ``` 843 /// use std::ffi::CString; 844 /// 845 /// let nul_error = CString::new("foo\0bar").unwrap_err(); 846 /// assert_eq!(nul_error.into_vec(), b"foo\0bar"); 847 /// ``` 848 pub fn into_vec(self) -> Vec<u8> { 849 self.1 850 } 851 } 852 853 impl fmt::Display for NulError { 854 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 855 write!(f, "nul byte found in provided data at position: {}", self.0) 856 } 857 } 858 859 impl fmt::Display for FromBytesWithNulError { 860 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 861 f.write_str(self.description())?; 862 if let FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind { 863 write!(f, " at byte pos {}", pos)?; 864 } 865 Ok(()) 866 } 867 } 868 869 impl IntoStringError { 870 /// Consumes this error, returning original [`CString`] which generated the 871 /// error. 872 /// 873 /// [`CString`]: struct.CString.html 874 pub fn into_cstring(self) -> CString { 875 self.inner 876 } 877 878 /// Access the underlying UTF-8 error that was the cause of this error. 879 pub fn utf8_error(&self) -> Utf8Error { 880 self.error 881 } 882 883 fn description(&self) -> &str { 884 "C string contained non-utf8 bytes" 885 } 886 } 887 888 impl fmt::Display for IntoStringError { 889 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 890 self.description().fmt(f) 891 } 892 } 893 894 impl CStr { 895 /// Wraps a raw C string with a safe C string wrapper. 896 /// 897 /// This function will wrap the provided `ptr` with a `CStr` wrapper, which 898 /// allows inspection and interoperation of non-owned C strings. This method 899 /// is unsafe for a number of reasons: 900 /// 901 /// * There is no guarantee to the validity of `ptr`. 902 /// * The returned lifetime is not guaranteed to be the actual lifetime of 903 /// `ptr`. 904 /// * There is no guarantee that the memory pointed to by `ptr` contains a 905 /// valid nul terminator byte at the end of the string. 906 /// * It is not guaranteed that the memory pointed by `ptr` won't change 907 /// before the `CStr` has been destroyed. 908 /// 909 /// > **Note**: This operation is intended to be a 0-cost cast but it is 910 /// > currently implemented with an up-front calculation of the length of 911 /// > the string. This is not guaranteed to always be the case. 912 /// 913 /// # Examples 914 /// 915 /// ```ignore (extern-declaration) 916 /// # fn main() { 917 /// use std::ffi::CStr; 918 /// use std::os::raw::c_char; 919 /// 920 /// extern { 921 /// fn my_string() -> *const c_char; 922 /// } 923 /// 924 /// unsafe { 925 /// let slice = CStr::from_ptr(my_string()); 926 /// println!("string returned: {}", slice.to_str().unwrap()); 927 /// } 928 /// # } 929 /// ``` 930 pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr { 931 let len = strlen(ptr); 932 let ptr = ptr as *const u8; 933 CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1)) 934 } 935 936 /// Creates a C string wrapper from a byte slice. 937 /// 938 /// This function will cast the provided `bytes` to a `CStr` 939 /// wrapper after ensuring that the byte slice is nul-terminated 940 /// and does not contain any interior nul bytes. 941 /// 942 /// # Examples 943 /// 944 /// ``` 945 /// use std::ffi::CStr; 946 /// 947 /// let cstr = CStr::from_bytes_with_nul(b"hello\0"); 948 /// assert!(cstr.is_ok()); 949 /// ``` 950 /// 951 /// Creating a `CStr` without a trailing nul terminator is an error: 952 /// 953 /// ``` 954 /// use std::ffi::CStr; 955 /// 956 /// let c_str = CStr::from_bytes_with_nul(b"hello"); 957 /// assert!(c_str.is_err()); 958 /// ``` 959 /// 960 /// Creating a `CStr` with an interior nul byte is an error: 961 /// 962 /// ``` 963 /// use std::ffi::CStr; 964 /// 965 /// let c_str = CStr::from_bytes_with_nul(b"he\0llo\0"); 966 /// assert!(c_str.is_err()); 967 /// ``` 968 pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&CStr, FromBytesWithNulError> { 969 let nul_pos = memchr(0, bytes); 970 if let Some(nul_pos) = nul_pos { 971 if nul_pos + 1 != bytes.len() { 972 return Err(FromBytesWithNulError::interior_nul(nul_pos)); 973 } 974 Ok(unsafe { CStr::from_bytes_with_nul_unchecked(bytes) }) 975 } else { 976 Err(FromBytesWithNulError::not_nul_terminated()) 977 } 978 } 979 980 /// Unsafely creates a C string wrapper from a byte slice. 981 /// 982 /// This function will cast the provided `bytes` to a `CStr` wrapper without 983 /// performing any sanity checks. The provided slice **must** be nul-terminated 984 /// and not contain any interior nul bytes. 985 /// 986 /// # Examples 987 /// 988 /// ``` 989 /// use std::ffi::{CStr, CString}; 990 /// 991 /// unsafe { 992 /// let cstring = CString::new("hello").unwrap(); 993 /// let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul()); 994 /// assert_eq!(cstr, &*cstring); 995 /// } 996 /// ``` 997 #[inline] 998 pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr { 999 &*(bytes as *const [u8] as *const CStr) 1000 } 1001 1002 /// Returns the inner pointer to this C string. 1003 /// 1004 /// The returned pointer will be valid for as long as `self` is, and points 1005 /// to a contiguous region of memory terminated with a 0 byte to represent 1006 /// the end of the string. 1007 /// 1008 /// **WARNING** 1009 /// 1010 /// It is your responsibility to make sure that the underlying memory is not 1011 /// freed too early. For example, the following code will cause undefined 1012 /// behavior when `ptr` is used inside the `unsafe` block: 1013 /// 1014 /// ```no_run 1015 /// # #![allow(unused_must_use)] 1016 /// use std::ffi::{CString}; 1017 /// 1018 /// let ptr = CString::new("Hello").unwrap().as_ptr(); 1019 /// unsafe { 1020 /// // `ptr` is dangling 1021 /// *ptr; 1022 /// } 1023 /// ``` 1024 /// 1025 /// This happens because the pointer returned by `as_ptr` does not carry any 1026 /// lifetime information and the [`CString`] is deallocated immediately after 1027 /// the `CString::new("Hello").unwrap().as_ptr()` expression is evaluated. 1028 /// To fix the problem, bind the `CString` to a local variable: 1029 /// 1030 /// ```no_run 1031 /// # #![allow(unused_must_use)] 1032 /// use std::ffi::{CString}; 1033 /// 1034 /// let hello = CString::new("Hello").unwrap(); 1035 /// let ptr = hello.as_ptr(); 1036 /// unsafe { 1037 /// // `ptr` is valid because `hello` is in scope 1038 /// *ptr; 1039 /// } 1040 /// ``` 1041 /// 1042 /// This way, the lifetime of the `CString` in `hello` encompasses 1043 /// the lifetime of `ptr` and the `unsafe` block. 1044 /// 1045 /// [`CString`]: struct.CString.html 1046 #[inline] 1047 pub fn as_ptr(&self) -> *const c_char { 1048 self.inner.as_ptr() 1049 } 1050 1051 /// Converts this C string to a byte slice. 1052 /// 1053 /// The returned slice will **not** contain the trailing nul terminator that this C 1054 /// string has. 1055 /// 1056 /// > **Note**: This method is currently implemented as a constant-time 1057 /// > cast, but it is planned to alter its definition in the future to 1058 /// > perform the length calculation whenever this method is called. 1059 /// 1060 /// # Examples 1061 /// 1062 /// ``` 1063 /// use std::ffi::CStr; 1064 /// 1065 /// let c_str = CStr::from_bytes_with_nul(b"foo\0").unwrap(); 1066 /// assert_eq!(c_str.to_bytes(), b"foo"); 1067 /// ``` 1068 #[inline] 1069 pub fn to_bytes(&self) -> &[u8] { 1070 let bytes = self.to_bytes_with_nul(); 1071 &bytes[..bytes.len() - 1] 1072 } 1073 1074 /// Converts this C string to a byte slice containing the trailing 0 byte. 1075 /// 1076 /// This function is the equivalent of [`to_bytes`] except that it will retain 1077 /// the trailing nul terminator instead of chopping it off. 1078 /// 1079 /// > **Note**: This method is currently implemented as a 0-cost cast, but 1080 /// > it is planned to alter its definition in the future to perform the 1081 /// > length calculation whenever this method is called. 1082 /// 1083 /// [`to_bytes`]: #method.to_bytes 1084 /// 1085 /// # Examples 1086 /// 1087 /// ``` 1088 /// use std::ffi::CStr; 1089 /// 1090 /// let c_str = CStr::from_bytes_with_nul(b"foo\0").unwrap(); 1091 /// assert_eq!(c_str.to_bytes_with_nul(), b"foo\0"); 1092 /// ``` 1093 #[inline] 1094 pub fn to_bytes_with_nul(&self) -> &[u8] { 1095 unsafe { &*(&self.inner as *const [c_char] as *const [u8]) } 1096 } 1097 1098 /// Yields a [`&str`] slice if the `CStr` contains valid UTF-8. 1099 /// 1100 /// If the contents of the `CStr` are valid UTF-8 data, this 1101 /// function will return the corresponding [`&str`] slice. Otherwise, 1102 /// it will return an error with details of where UTF-8 validation failed. 1103 /// 1104 /// > **Note**: This method is currently implemented to check for validity 1105 /// > after a constant-time cast, but it is planned to alter its definition 1106 /// > in the future to perform the length calculation in addition to the 1107 /// > UTF-8 check whenever this method is called. 1108 /// 1109 /// [`&str`]: ../primitive.str.html 1110 /// 1111 /// # Examples 1112 /// 1113 /// ``` 1114 /// use std::ffi::CStr; 1115 /// 1116 /// let c_str = CStr::from_bytes_with_nul(b"foo\0").unwrap(); 1117 /// assert_eq!(c_str.to_str(), Ok("foo")); 1118 /// ``` 1119 pub fn to_str(&self) -> Result<&str, str::Utf8Error> { 1120 // NB: When CStr is changed to perform the length check in .to_bytes() 1121 // instead of in from_ptr(), it may be worth considering if this should 1122 // be rewritten to do the UTF-8 check inline with the length calculation 1123 // instead of doing it afterwards. 1124 str::from_utf8(self.to_bytes()) 1125 } 1126 1127 /// Converts a `CStr` into a [`Cow`]`<`[`str`]`>`. 1128 /// 1129 /// If the contents of the `CStr` are valid UTF-8 data, this 1130 /// function will return a [`Cow`]`::`[`Borrowed`]`(`[`&str`]`)` 1131 /// with the the corresponding [`&str`] slice. Otherwise, it will 1132 /// replace any invalid UTF-8 sequences with 1133 /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a 1134 /// [`Cow`]`::`[`Owned`]`(`[`String`]`)` with the result. 1135 /// 1136 /// > **Note**: This method is currently implemented to check for validity 1137 /// > after a constant-time cast, but it is planned to alter its definition 1138 /// > in the future to perform the length calculation in addition to the 1139 /// > UTF-8 check whenever this method is called. 1140 /// 1141 /// [`Cow`]: ../borrow/enum.Cow.html 1142 /// [`Borrowed`]: ../borrow/enum.Cow.html#variant.Borrowed 1143 /// [`Owned`]: ../borrow/enum.Cow.html#variant.Owned 1144 /// [`str`]: ../primitive.str.html 1145 /// [`String`]: ../string/struct.String.html 1146 /// [U+FFFD]: ../char/constant.REPLACEMENT_CHARACTER.html 1147 /// 1148 /// # Examples 1149 /// 1150 /// Calling `to_string_lossy` on a `CStr` containing valid UTF-8: 1151 /// 1152 /// ``` 1153 /// use std::borrow::Cow; 1154 /// use std::ffi::CStr; 1155 /// 1156 /// let c_str = CStr::from_bytes_with_nul(b"Hello World\0").unwrap(); 1157 /// assert_eq!(c_str.to_string_lossy(), Cow::Borrowed("Hello World")); 1158 /// ``` 1159 /// 1160 /// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8: 1161 /// 1162 /// ``` 1163 /// use std::borrow::Cow; 1164 /// use std::ffi::CStr; 1165 /// 1166 /// let c_str = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0").unwrap(); 1167 /// assert_eq!( 1168 /// c_str.to_string_lossy(), 1169 /// Cow::Owned(String::from("Hello �World")) as Cow<str> 1170 /// ); 1171 /// ``` 1172 pub fn to_string_lossy(&self) -> Cow<str> { 1173 String::from_utf8_lossy(self.to_bytes()) 1174 } 1175 1176 /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating. 1177 /// 1178 /// [`Box`]: ../boxed/struct.Box.html 1179 /// [`CString`]: struct.CString.html 1180 /// 1181 /// # Examples 1182 /// 1183 /// ``` 1184 /// use std::ffi::CString; 1185 /// 1186 /// let c_string = CString::new(b"foo".to_vec()).unwrap(); 1187 /// let boxed = c_string.into_boxed_c_str(); 1188 /// assert_eq!(boxed.into_c_string(), CString::new("foo").unwrap()); 1189 /// ``` 1190 pub fn into_c_string(self: Box<CStr>) -> CString { 1191 let raw = Box::into_raw(self) as *mut [u8]; 1192 CString { 1193 inner: unsafe { Box::from_raw(raw) }, 1194 } 1195 } 1196 } 1197 1198 impl PartialEq for CStr { 1199 fn eq(&self, other: &CStr) -> bool { 1200 self.to_bytes().eq(other.to_bytes()) 1201 } 1202 } 1203 1204 impl Eq for CStr {} 1205 1206 impl PartialOrd for CStr { 1207 fn partial_cmp(&self, other: &CStr) -> Option<Ordering> { 1208 self.to_bytes().partial_cmp(&other.to_bytes()) 1209 } 1210 } 1211 1212 impl Ord for CStr { 1213 fn cmp(&self, other: &CStr) -> Ordering { 1214 self.to_bytes().cmp(&other.to_bytes()) 1215 } 1216 } 1217 1218 impl ToOwned for CStr { 1219 type Owned = CString; 1220 1221 fn to_owned(&self) -> CString { 1222 CString { 1223 inner: self.to_bytes_with_nul().into(), 1224 } 1225 } 1226 } 1227 1228 impl<'a> From<&'a CStr> for CString { 1229 fn from(s: &'a CStr) -> CString { 1230 s.to_owned() 1231 } 1232 } 1233 1234 impl ops::Index<ops::RangeFull> for CString { 1235 type Output = CStr; 1236 1237 #[inline] 1238 fn index(&self, _index: ops::RangeFull) -> &CStr { 1239 self 1240 } 1241 } 1242 1243 impl AsRef<CStr> for CStr { 1244 #[inline] 1245 fn as_ref(&self) -> &CStr { 1246 self 1247 } 1248 } 1249 1250 impl AsRef<CStr> for CString { 1251 #[inline] 1252 fn as_ref(&self) -> &CStr { 1253 self 1254 } 1255 } 1256