Mercurial > crates > nonstick
comparison src/pam_ffi/memory.rs @ 73:ac6881304c78
Do conversations, along with way too much stuff.
This implements conversations, along with all the memory management
brouhaha that goes along with it. The conversation now lives directly
on the handle rather than being a thing you have to get from it
and then call manually. It Turns Out this makes things a lot easier!
I guess we reorganized things again. For the last time. For real.
I promise.
This all passes ASAN, so it seems Pretty Good!
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 05 Jun 2025 03:41:38 -0400 |
parents | 47eb242a4f88 |
children |
comparison
equal
deleted
inserted
replaced
72:47eb242a4f88 | 73:ac6881304c78 |
---|---|
6 use std::marker::{PhantomData, PhantomPinned}; | 6 use std::marker::{PhantomData, PhantomPinned}; |
7 use std::result::Result as StdResult; | 7 use std::result::Result as StdResult; |
8 use std::{ptr, slice}; | 8 use std::{ptr, slice}; |
9 | 9 |
10 /// Makes whatever it's in not [`Send`], [`Sync`], or [`Unpin`]. | 10 /// Makes whatever it's in not [`Send`], [`Sync`], or [`Unpin`]. |
11 pub type Immovable = PhantomData<(*mut u8, PhantomPinned)>; | 11 #[repr(C)] |
12 #[derive(Debug)] | |
13 pub struct Immovable(pub PhantomData<(*mut u8, PhantomPinned)>); | |
12 | 14 |
13 /// Safely converts a `&str` option to a `CString` option. | 15 /// Safely converts a `&str` option to a `CString` option. |
14 pub fn option_cstr(prompt: Option<&str>) -> Result<Option<CString>> { | 16 pub fn option_cstr(prompt: Option<&str>) -> Result<Option<CString>> { |
15 prompt | 17 prompt |
16 .map(CString::new) | 18 .map(CString::new) |
69 if let Some(nul) = data.iter().position(|x| *x == 0) { | 71 if let Some(nul) = data.iter().position(|x| *x == 0) { |
70 return Err(NulError(nul)); | 72 return Err(NulError(nul)); |
71 } | 73 } |
72 unsafe { | 74 unsafe { |
73 let data_alloc = libc::calloc(data.len() + 1, 1); | 75 let data_alloc = libc::calloc(data.len() + 1, 1); |
74 libc::memcpy(data_alloc, data.as_ptr() as *const c_void, data.len()); | 76 libc::memcpy(data_alloc, data.as_ptr().cast(), data.len()); |
75 Ok(data_alloc.cast()) | 77 Ok(data_alloc.cast()) |
76 } | 78 } |
77 } | 79 } |
78 | 80 |
79 /// Writes zeroes over the contents of a C string. | 81 /// Writes zeroes over the contents of a C string. |
83 /// # Safety | 85 /// # Safety |
84 /// | 86 /// |
85 /// It's up to you to provide a valid C string. | 87 /// It's up to you to provide a valid C string. |
86 pub unsafe fn zero_c_string(cstr: *mut c_void) { | 88 pub unsafe fn zero_c_string(cstr: *mut c_void) { |
87 if !cstr.is_null() { | 89 if !cstr.is_null() { |
88 libc::memset(cstr, 0, libc::strlen(cstr as *const c_char)); | 90 libc::memset(cstr, 0, libc::strlen(cstr.cast())); |
89 } | 91 } |
90 } | 92 } |
91 | 93 |
92 /// Binary data used in requests and responses. | 94 /// Binary data used in requests and responses. |
93 /// | 95 /// |
111 pub fn alloc(source: &[u8], data_type: u8) -> StdResult<*mut CBinaryData, TooBigError> { | 113 pub fn alloc(source: &[u8], data_type: u8) -> StdResult<*mut CBinaryData, TooBigError> { |
112 let buffer_size = u32::try_from(source.len() + 5).map_err(|_| TooBigError { | 114 let buffer_size = u32::try_from(source.len() + 5).map_err(|_| TooBigError { |
113 max: (u32::MAX - 5) as usize, | 115 max: (u32::MAX - 5) as usize, |
114 actual: source.len(), | 116 actual: source.len(), |
115 })?; | 117 })?; |
118 // SAFETY: We're only allocating here. | |
116 let data = unsafe { | 119 let data = unsafe { |
117 let dest_buffer = libc::malloc(buffer_size as usize) as *mut CBinaryData; | 120 let dest_buffer: *mut CBinaryData = libc::malloc(buffer_size as usize).cast(); |
118 let data = &mut *dest_buffer; | 121 let data = &mut *dest_buffer; |
119 data.total_length = buffer_size.to_be_bytes(); | 122 data.total_length = buffer_size.to_be_bytes(); |
120 data.data_type = data_type; | 123 data.data_type = data_type; |
121 let dest = data.data.as_mut_ptr(); | 124 let dest = data.data.as_mut_ptr(); |
122 libc::memcpy( | 125 libc::memcpy(dest.cast(), source.as_ptr().cast(), source.len()); |
123 dest as *mut c_void, | |
124 source.as_ptr() as *const c_void, | |
125 source.len(), | |
126 ); | |
127 dest_buffer | 126 dest_buffer |
128 }; | 127 }; |
129 Ok(data) | 128 Ok(data) |
130 } | 129 } |
131 | 130 |