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 {