Mercurial > crates > nonstick
comparison src/libpam/memory.rs @ 79:2128123b9406
Format (oops!) and make some fun and/or stupid conversions available.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sun, 08 Jun 2025 04:21:58 -0400 |
parents | 002adfb98c5c |
children | 5aa1a010f1e8 |
comparison
equal
deleted
inserted
replaced
78:002adfb98c5c | 79:2128123b9406 |
---|---|
85 pub fn malloc_str(text: &str) -> Result<*mut c_char> { | 85 pub fn malloc_str(text: &str) -> Result<*mut c_char> { |
86 let data = text.as_bytes(); | 86 let data = text.as_bytes(); |
87 if data.contains(&0) { | 87 if data.contains(&0) { |
88 return Err(ErrorCode::ConversationError); | 88 return Err(ErrorCode::ConversationError); |
89 } | 89 } |
90 // +1 for the null terminator | |
90 let data_alloc: *mut c_char = calloc(data.len() + 1); | 91 let data_alloc: *mut c_char = calloc(data.len() + 1); |
91 // SAFETY: we just allocated this and we have enough room. | 92 // SAFETY: we just allocated this and we have enough room. |
92 unsafe { | 93 unsafe { |
93 libc::memcpy(data_alloc.cast(), data.as_ptr().cast(), data.len()); | 94 libc::memcpy(data_alloc.cast(), data.as_ptr().cast(), data.len()); |
94 } | 95 } |
156 self.data_type = 0; | 157 self.data_type = 0; |
157 self.total_length = [0; 4]; | 158 self.total_length = [0; 4]; |
158 } | 159 } |
159 } | 160 } |
160 | 161 |
161 impl<'a> From<&'a CBinaryData> for (&'a[u8], u8) { | 162 impl<'a> From<&'a CBinaryData> for (&'a [u8], u8) { |
162 fn from(value: &'a CBinaryData) -> Self { | 163 fn from(value: &'a CBinaryData) -> Self { |
163 (unsafe { slice::from_raw_parts(value.data.as_ptr(), value.length()) }, | 164 ( |
164 value.data_type ) | 165 unsafe { slice::from_raw_parts(value.data.as_ptr(), value.length()) }, |
166 value.data_type, | |
167 ) | |
168 } | |
169 } | |
170 | |
171 impl From<&'_ CBinaryData> for BinaryData { | |
172 fn from(value: &'_ CBinaryData) -> Self { | |
173 // This is a dumb trick but I like it because it is simply the presence | |
174 // of `.map(|z: (_, _)| z)` in the middle of this that gives | |
175 // type inference the hint it needs to make this work. | |
176 let [ret] = [value].map(Into::into).map(|z: (_, _)| z).map(Into::into); | |
177 ret | |
165 } | 178 } |
166 } | 179 } |
167 | 180 |
168 impl From<Option<&'_ CBinaryData>> for BinaryData { | 181 impl From<Option<&'_ CBinaryData>> for BinaryData { |
169 fn from(value: Option<&CBinaryData>) -> Self { | 182 fn from(value: Option<&CBinaryData>) -> Self { |
170 // This is a dumb trick but I like it because it is simply the presence | 183 value.map(Into::into).unwrap_or_default() |
171 // of `.map(|(x, y)| (x, y))` in the middle of this that gives | |
172 // type inference the hint it needs to make this work. | |
173 value | |
174 .map(Into::into) | |
175 .map(|(data, data_type)| (data, data_type)) | |
176 .map(Into::into) | |
177 .unwrap_or_default() | |
178 } | 184 } |
179 } | 185 } |
180 | 186 |
181 #[cfg(test)] | 187 #[cfg(test)] |
182 mod tests { | 188 mod tests { |
183 use super::{free, ErrorCode, CString, copy_pam_string, malloc_str, option_cstr, prompt_ptr, zero_c_string}; | 189 use super::{ |
190 copy_pam_string, free, malloc_str, option_cstr, prompt_ptr, zero_c_string, CString, | |
191 ErrorCode, | |
192 }; | |
184 #[test] | 193 #[test] |
185 fn test_strings() { | 194 fn test_strings() { |
186 let str = malloc_str("hello there").unwrap(); | 195 let str = malloc_str("hello there").unwrap(); |
187 malloc_str("hell\0 there").unwrap_err(); | 196 malloc_str("hell\0 there").unwrap_err(); |
188 unsafe { | 197 unsafe { |