Mercurial > crates > nonstick
annotate 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 |
rev | line source |
---|---|
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
1 //! Things for dealing with memory. |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
2 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
3 use crate::ErrorCode; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
4 use crate::Result; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
5 use std::ffi::{c_char, c_void, CStr, CString}; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
6 use std::marker::{PhantomData, PhantomPinned}; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
7 use std::result::Result as StdResult; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
8 use std::{ptr, slice}; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
9 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
10 /// Makes whatever it's in not [`Send`], [`Sync`], or [`Unpin`]. |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
11 #[repr(C)] |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
12 #[derive(Debug)] |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
13 pub struct Immovable(pub PhantomData<(*mut u8, PhantomPinned)>); |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
14 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
15 /// Safely converts a `&str` option to a `CString` option. |
64
bbe84835d6db
More organization; add lots of docs.
Paul Fisher <paul@pfish.zone>
parents:
60
diff
changeset
|
16 pub fn option_cstr(prompt: Option<&str>) -> Result<Option<CString>> { |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
17 prompt |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
18 .map(CString::new) |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
19 .transpose() |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
20 .map_err(|_| ErrorCode::ConversationError) |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
21 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
22 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
23 /// Gets the pointer to the given CString, or a null pointer if absent. |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
24 pub fn prompt_ptr(prompt: Option<&CString>) -> *const c_char { |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
25 match prompt { |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
26 Some(c_str) => c_str.as_ptr(), |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
27 None => ptr::null(), |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
28 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
29 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
30 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
31 /// Creates an owned copy of a string that is returned from a |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
32 /// <code>pam_get_<var>whatever</var></code> function. |
72 | 33 /// |
34 /// # Safety | |
35 /// | |
36 /// It's on you to provide a valid string. | |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
37 pub unsafe fn copy_pam_string(result_ptr: *const libc::c_char) -> Result<String> { |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
38 // We really shouldn't get a null pointer back here, but if we do, return nothing. |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
39 if result_ptr.is_null() { |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
40 return Ok(String::new()); |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
41 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
42 let bytes = unsafe { CStr::from_ptr(result_ptr) }; |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
43 bytes |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
44 .to_str() |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
45 .map(String::from) |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
46 .map_err(|_| ErrorCode::ConversationError) |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
47 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
48 |
72 | 49 /// Wraps a string returned from PAM as an `Option<&str>`. |
50 pub unsafe fn wrap_string<'a>(data: *const libc::c_char) -> Result<Option<&'a str>> { | |
51 let ret = if data.is_null() { | |
52 None | |
53 } else { | |
54 Some( | |
55 CStr::from_ptr(data) | |
56 .to_str() | |
57 .map_err(|_| ErrorCode::ConversationError)?, | |
58 ) | |
59 }; | |
60 Ok(ret) | |
61 } | |
62 | |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
63 /// Allocates a string with the given contents on the C heap. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
64 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
65 /// This is like [`CString::new`](std::ffi::CString::new), but: |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
66 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
67 /// - it allocates data on the C heap with [`libc::malloc`]. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
68 /// - it doesn't take ownership of the data passed in. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
69 pub fn malloc_str(text: impl AsRef<str>) -> StdResult<*mut c_char, NulError> { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
70 let data = text.as_ref().as_bytes(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
71 if let Some(nul) = data.iter().position(|x| *x == 0) { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
72 return Err(NulError(nul)); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
73 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
74 unsafe { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
75 let data_alloc = libc::calloc(data.len() + 1, 1); |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
76 libc::memcpy(data_alloc, data.as_ptr().cast(), data.len()); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
77 Ok(data_alloc.cast()) |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
78 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
79 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
80 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
81 /// Writes zeroes over the contents of a C string. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
82 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
83 /// This won't overwrite a null pointer. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
84 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
85 /// # Safety |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
86 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
87 /// It's up to you to provide a valid C string. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
88 pub unsafe fn zero_c_string(cstr: *mut c_void) { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
89 if !cstr.is_null() { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
90 libc::memset(cstr, 0, libc::strlen(cstr.cast())); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
91 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
92 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
93 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
94 /// Binary data used in requests and responses. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
95 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
96 /// This is an unsized data type whose memory goes beyond its data. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
97 /// This must be allocated on the C heap. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
98 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
99 /// A Linux-PAM extension. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
100 #[repr(C)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
101 pub struct CBinaryData { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
102 /// The total length of the structure; a u32 in network byte order (BE). |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
103 total_length: [u8; 4], |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
104 /// A tag of undefined meaning. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
105 data_type: u8, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
106 /// Pointer to an array of length [`length`](Self::length) − 5 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
107 data: [u8; 0], |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
108 _marker: Immovable, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
109 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
110 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
111 impl CBinaryData { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
112 /// Copies the given data to a new BinaryData on the heap. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
113 pub fn alloc(source: &[u8], data_type: u8) -> StdResult<*mut CBinaryData, TooBigError> { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
114 let buffer_size = u32::try_from(source.len() + 5).map_err(|_| TooBigError { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
115 max: (u32::MAX - 5) as usize, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
116 actual: source.len(), |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
117 })?; |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
118 // SAFETY: We're only allocating here. |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
119 let data = unsafe { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
120 let dest_buffer: *mut CBinaryData = libc::malloc(buffer_size as usize).cast(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
121 let data = &mut *dest_buffer; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
122 data.total_length = buffer_size.to_be_bytes(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
123 data.data_type = data_type; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
124 let dest = data.data.as_mut_ptr(); |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
125 libc::memcpy(dest.cast(), source.as_ptr().cast(), source.len()); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
126 dest_buffer |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
127 }; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
128 Ok(data) |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
129 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
130 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
131 fn length(&self) -> usize { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
132 u32::from_be_bytes(self.total_length).saturating_sub(5) as usize |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
133 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
134 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
135 pub fn contents(&self) -> &[u8] { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
136 unsafe { slice::from_raw_parts(self.data.as_ptr(), self.length()) } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
137 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
138 pub fn data_type(&self) -> u8 { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
139 self.data_type |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
140 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
141 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
142 /// Clears this data and frees it. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
143 pub unsafe fn zero_contents(&mut self) { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
144 let contents = slice::from_raw_parts_mut(self.data.as_mut_ptr(), self.length()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
145 for v in contents { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
146 *v = 0 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
147 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
148 self.data_type = 0; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
149 self.total_length = [0; 4]; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
150 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
151 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
152 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
153 #[derive(Debug, thiserror::Error)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
154 #[error("null byte within input at byte {0}")] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
155 pub struct NulError(pub usize); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
156 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
157 /// Returned when trying to fit too much data into a binary message. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
158 #[derive(Debug, thiserror::Error)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
159 #[error("cannot create a message of {actual} bytes; maximum is {max}")] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
160 pub struct TooBigError { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
161 pub actual: usize, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
162 pub max: usize, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
163 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
164 |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
165 #[cfg(test)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
166 mod tests { |
72 | 167 use super::{copy_pam_string, malloc_str, option_cstr, prompt_ptr, zero_c_string}; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
168 use crate::ErrorCode; |
72 | 169 use std::ffi::CString; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
170 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
171 fn test_strings() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
172 let str = malloc_str("hello there").unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
173 malloc_str("hell\0 there").unwrap_err(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
174 unsafe { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
175 let copied = copy_pam_string(str.cast()).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
176 assert_eq!("hello there", copied); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
177 zero_c_string(str.cast()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
178 let idx_three = str.add(3).as_mut().unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
179 *idx_three = 0x80u8 as i8; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
180 let zeroed = copy_pam_string(str.cast()).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
181 assert!(zeroed.is_empty()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
182 libc::free(str.cast()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
183 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
184 } |
72 | 185 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
186 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
187 fn test_option_str() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
188 let good = option_cstr(Some("whatever")).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
189 assert_eq!("whatever", good.unwrap().to_str().unwrap()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
190 let no_str = option_cstr(None).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
191 assert!(no_str.is_none()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
192 let bad_str = option_cstr(Some("what\0ever")).unwrap_err(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
193 assert_eq!(ErrorCode::ConversationError, bad_str); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
194 } |
72 | 195 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
196 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
197 fn test_prompt() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
198 let prompt_cstr = CString::new("good").ok(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
199 let prompt = prompt_ptr(prompt_cstr.as_ref()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
200 assert!(!prompt.is_null()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
201 let no_prompt = prompt_ptr(None); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
202 assert!(no_prompt.is_null()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
203 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
204 } |