1 // Copyright 2016 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.
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.
13 // Test that `CString::new("hello").unwrap().as_ptr()` pattern
17 use std::ffi::{CString, CStr};
18 use std::os::raw::c_char;
19 use std::process::{Command, Stdio};
22 let args: Vec<String> = env::args().collect();
23 if args.len() > 1 && args[1] == "child" {
24 // Repeat several times to be more confident that
25 // it is `Drop` for `CString` that does the cleanup,
26 // and not just some lucky UB.
27 let xs = vec![CString::new("Hello").unwrap(); 10];
28 let ys = xs.iter().map(|s| s.as_ptr()).collect::<Vec<_>>();
30 assert!(ys.into_iter().any(is_hello));
34 let output = Command::new(&args[0]).arg("child").output().unwrap();
35 assert!(!output.status.success());
38 fn is_hello(s: *const c_char) -> bool {
39 // `s` is a dangling pointer and reading it is technically
40 // undefined behavior. But we want to prevent the most diabolical
41 // kind of UB (apart from nasal demons): reading a value that was
42 // previously written.
44 // Segfaulting or reading an empty string is Ok,
45 // reading "Hello" is bad.
46 let s = unsafe { CStr::from_ptr(s) };
47 let hello = CString::new("Hello").unwrap();