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 { |
