]> git.lizzy.rs Git - rust.git/blob - library/alloc/src/ffi/c_str/tests.rs
:arrow_up: rust-analyzer
[rust.git] / library / alloc / src / ffi / c_str / tests.rs
1 use super::*;
2 use crate::rc::Rc;
3 use crate::sync::Arc;
4 use core::assert_matches::assert_matches;
5 use core::ffi::FromBytesUntilNulError;
6 use core::hash::{Hash, Hasher};
7
8 #[allow(deprecated)]
9 use core::hash::SipHasher13 as DefaultHasher;
10
11 #[test]
12 fn c_to_rust() {
13     let data = b"123\0";
14     let ptr = data.as_ptr() as *const c_char;
15     unsafe {
16         assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123");
17         assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0");
18     }
19 }
20
21 #[test]
22 fn simple() {
23     let s = CString::new("1234").unwrap();
24     assert_eq!(s.as_bytes(), b"1234");
25     assert_eq!(s.as_bytes_with_nul(), b"1234\0");
26 }
27
28 #[test]
29 fn build_with_zero1() {
30     assert!(CString::new(&b"\0"[..]).is_err());
31 }
32 #[test]
33 fn build_with_zero2() {
34     assert!(CString::new(vec![0]).is_err());
35 }
36
37 #[test]
38 fn formatted() {
39     let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap();
40     assert_eq!(format!("{s:?}"), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#);
41 }
42
43 #[test]
44 fn borrowed() {
45     unsafe {
46         let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
47         assert_eq!(s.to_bytes(), b"12");
48         assert_eq!(s.to_bytes_with_nul(), b"12\0");
49     }
50 }
51
52 #[test]
53 fn to_owned() {
54     let data = b"123\0";
55     let ptr = data.as_ptr() as *const c_char;
56
57     let owned = unsafe { CStr::from_ptr(ptr).to_owned() };
58     assert_eq!(owned.as_bytes_with_nul(), data);
59 }
60
61 #[test]
62 fn equal_hash() {
63     let data = b"123\xE2\xFA\xA6\0";
64     let ptr = data.as_ptr() as *const c_char;
65     let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) };
66
67     #[allow(deprecated)]
68     let mut s = DefaultHasher::new();
69     cstr.hash(&mut s);
70     let cstr_hash = s.finish();
71     #[allow(deprecated)]
72     let mut s = DefaultHasher::new();
73     CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s);
74     let cstring_hash = s.finish();
75
76     assert_eq!(cstr_hash, cstring_hash);
77 }
78
79 #[test]
80 fn from_bytes_with_nul() {
81     let data = b"123\0";
82     let cstr = CStr::from_bytes_with_nul(data);
83     assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..]));
84     let cstr = CStr::from_bytes_with_nul(data);
85     assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..]));
86
87     unsafe {
88         let cstr = CStr::from_bytes_with_nul(data);
89         let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
90         assert_eq!(cstr, Ok(cstr_unchecked));
91     }
92 }
93
94 #[test]
95 fn from_bytes_with_nul_unterminated() {
96     let data = b"123";
97     let cstr = CStr::from_bytes_with_nul(data);
98     assert!(cstr.is_err());
99 }
100
101 #[test]
102 fn from_bytes_with_nul_interior() {
103     let data = b"1\023\0";
104     let cstr = CStr::from_bytes_with_nul(data);
105     assert!(cstr.is_err());
106 }
107
108 #[test]
109 fn cstr_from_bytes_until_nul() {
110     // Test an empty slice. This should fail because it
111     // does not contain a nul byte.
112     let b = b"";
113     assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. }));
114
115     // Test a non-empty slice, that does not contain a nul byte.
116     let b = b"hello";
117     assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. }));
118
119     // Test an empty nul-terminated string
120     let b = b"\0";
121     let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
122     assert_eq!(r.to_bytes(), b"");
123
124     // Test a slice with the nul byte in the middle
125     let b = b"hello\0world!";
126     let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
127     assert_eq!(r.to_bytes(), b"hello");
128
129     // Test a slice with the nul byte at the end
130     let b = b"hello\0";
131     let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
132     assert_eq!(r.to_bytes(), b"hello");
133
134     // Test a slice with two nul bytes at the end
135     let b = b"hello\0\0";
136     let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
137     assert_eq!(r.to_bytes(), b"hello");
138
139     // Test a slice containing lots of nul bytes
140     let b = b"\0\0\0\0";
141     let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
142     assert_eq!(r.to_bytes(), b"");
143 }
144
145 #[test]
146 fn into_boxed() {
147     let orig: &[u8] = b"Hello, world!\0";
148     let cstr = CStr::from_bytes_with_nul(orig).unwrap();
149     let boxed: Box<CStr> = Box::from(cstr);
150     let cstring = cstr.to_owned().into_boxed_c_str().into_c_string();
151     assert_eq!(cstr, &*boxed);
152     assert_eq!(&*boxed, &*cstring);
153     assert_eq!(&*cstring, cstr);
154 }
155
156 #[test]
157 fn boxed_default() {
158     let boxed = <Box<CStr>>::default();
159     assert_eq!(boxed.to_bytes_with_nul(), &[0]);
160 }
161
162 #[test]
163 fn test_c_str_clone_into() {
164     let mut c_string = CString::new("lorem").unwrap();
165     let c_ptr = c_string.as_ptr();
166     let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap();
167     c_str.clone_into(&mut c_string);
168     assert_eq!(c_str, c_string.as_c_str());
169     // The exact same size shouldn't have needed to move its allocation
170     assert_eq!(c_ptr, c_string.as_ptr());
171 }
172
173 #[test]
174 fn into_rc() {
175     let orig: &[u8] = b"Hello, world!\0";
176     let cstr = CStr::from_bytes_with_nul(orig).unwrap();
177     let rc: Rc<CStr> = Rc::from(cstr);
178     let arc: Arc<CStr> = Arc::from(cstr);
179
180     assert_eq!(&*rc, cstr);
181     assert_eq!(&*arc, cstr);
182
183     let rc2: Rc<CStr> = Rc::from(cstr.to_owned());
184     let arc2: Arc<CStr> = Arc::from(cstr.to_owned());
185
186     assert_eq!(&*rc2, cstr);
187     assert_eq!(&*arc2, cstr);
188 }
189
190 #[test]
191 fn cstr_const_constructor() {
192     const CSTR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0") };
193
194     assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
195 }
196
197 #[test]
198 fn cstr_index_from() {
199     let original = b"Hello, world!\0";
200     let cstr = CStr::from_bytes_with_nul(original).unwrap();
201     let result = CStr::from_bytes_with_nul(&original[7..]).unwrap();
202
203     assert_eq!(&cstr[7..], result);
204 }
205
206 #[test]
207 #[should_panic]
208 fn cstr_index_from_empty() {
209     let original = b"Hello, world!\0";
210     let cstr = CStr::from_bytes_with_nul(original).unwrap();
211     let _ = &cstr[original.len()..];
212 }
213
214 #[test]
215 fn c_string_from_empty_string() {
216     let original = "";
217     let cstring = CString::new(original).unwrap();
218     assert_eq!(original.as_bytes(), cstring.as_bytes());
219     assert_eq!([b'\0'], cstring.as_bytes_with_nul());
220 }
221
222 #[test]
223 fn c_str_from_empty_string() {
224     let original = b"\0";
225     let cstr = CStr::from_bytes_with_nul(original).unwrap();
226     assert_eq!([] as [u8; 0], cstr.to_bytes());
227     assert_eq!([b'\0'], cstr.to_bytes_with_nul());
228 }