annotate src/pam_ffi/response.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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
1 //! Types used when dealing with PAM conversations.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
2
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
3 use crate::conv::BinaryData;
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
4 use crate::pam_ffi::memory;
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
5 use crate::pam_ffi::memory::{CBinaryData, Immovable, NulError, TooBigError};
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
6 use crate::Response;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
7 use std::ffi::{c_int, c_void, CStr};
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
8 use std::ops::{Deref, DerefMut};
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
9 use std::result::Result as StdResult;
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
10 use std::str::Utf8Error;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
11 use std::{iter, mem, ptr, slice};
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
12
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
13 #[repr(transparent)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
14 #[derive(Debug)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
15 pub struct RawTextResponse(RawResponse);
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
16
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
17 impl RawTextResponse {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
18 /// Interprets the provided `RawResponse` as a text response.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
19 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
20 /// # Safety
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
21 ///
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
22 /// It's up to you to provide a response that is a `RawTextResponse`.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
23 pub unsafe fn upcast(from: &mut RawResponse) -> &mut Self {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
24 // SAFETY: We're provided a valid reference.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
25 &mut *(from as *mut RawResponse).cast::<Self>()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
26 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
27
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
28 /// Fills in the provided `RawResponse` with the given text.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
29 ///
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
30 /// You are responsible for calling [`free`](Self::free_contents)
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
31 /// on the pointer you get back when you're done with it.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
32 pub fn fill(dest: &mut RawResponse, text: impl AsRef<str>) -> StdResult<&mut Self, NulError> {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
33 dest.data = memory::malloc_str(text)?.cast();
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
34 // SAFETY: We just filled this in so we know it's a text response.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
35 Ok(unsafe { Self::upcast(dest) })
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
36 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
37
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
38 /// Gets the string stored in this response.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
39 pub fn contents(&self) -> StdResult<&str, Utf8Error> {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
40 if self.0.data.is_null() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
41 Ok("")
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
42 } else {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
43 // SAFETY: This data is either passed from PAM (so we are forced to
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
44 // trust it) or was created by us in TextResponseInner::alloc.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
45 // In either case, it's going to be a valid null-terminated string.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
46 unsafe { CStr::from_ptr(self.0.data.cast()) }.to_str()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
47 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
48 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
49
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
50 /// Releases memory owned by this response.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
51 pub fn free_contents(&mut self) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
52 // SAFETY: We know we own this data.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
53 // After we're done, it will be null.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
54 unsafe {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
55 memory::zero_c_string(self.0.data);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
56 libc::free(self.0.data);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
57 self.0.data = ptr::null_mut()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
58 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
59 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
60 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
61
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
62 /// A [`RawResponse`] with [`CBinaryData`] in it.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
63 #[repr(transparent)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
64 #[derive(Debug)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
65 pub struct RawBinaryResponse(RawResponse);
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
66
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
67 impl RawBinaryResponse {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
68 /// Interprets the provided `RawResponse` as a binary response.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
69 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
70 /// # Safety
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
71 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
72 /// It's up to you to provide a response that is a `RawBinaryResponse`.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
73 pub unsafe fn upcast(from: &mut RawResponse) -> &mut Self {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
74 // SAFETY: We're provided a valid reference.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
75 &mut *(from as *mut RawResponse).cast::<Self>()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
76 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
77
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
78 /// Fills in a `RawResponse` with the provided binary data.
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
79 ///
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
80 /// The `data_type` is a tag you can use for whatever.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
81 /// It is passed through PAM unchanged.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
82 ///
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
83 /// The referenced data is copied to the C heap. We do not take ownership.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
84 /// You are responsible for calling [`free`](Self::free_contents)
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
85 /// on the pointer you get back when you're done with it.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
86 pub fn fill<'a>(
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
87 dest: &'a mut RawResponse,
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
88 data: &[u8],
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
89 data_type: u8,
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
90 ) -> StdResult<&'a mut Self, TooBigError> {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
91 dest.data = CBinaryData::alloc(data, data_type)?.cast();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
92 // SAFETY: We just filled this in, so we know it's binary.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
93 Ok(unsafe { Self::upcast(dest) })
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
94 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
95
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
96 /// Gets the binary data in this response.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
97 pub fn data(&self) -> &[u8] {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
98 self.contents().map(CBinaryData::contents).unwrap_or(&[])
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
99 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
100
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
101 /// Gets the `data_type` tag that was embedded with the message.
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
102 pub fn data_type(&self) -> u8 {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
103 self.contents().map(CBinaryData::data_type).unwrap_or(0)
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
104 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
105
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
106 fn contents(&self) -> Option<&CBinaryData> {
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
107 // SAFETY: This was either something we got from PAM (in which case
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
108 // we trust it), or something that was created with
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
109 // BinaryResponseInner::alloc. In both cases, it points to valid data.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
110 unsafe { self.0.data.cast::<CBinaryData>().as_ref() }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
111 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
112
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
113 pub fn to_owned(&self) -> BinaryData {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
114 BinaryData::new(self.data().into(), self.data_type())
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
115 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
116
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
117 /// Releases memory owned by this response.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
118 pub fn free_contents(&mut self) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
119 // SAFETY: We know that our data pointer is either valid or null.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
120 // Once we're done, it's null and the response is safe.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
121 unsafe {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
122 let data_ref = self.0.data.cast::<CBinaryData>().as_mut();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
123 if let Some(d) = data_ref {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
124 d.zero_contents()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
125 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
126 libc::free(self.0.data);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
127 self.0.data = ptr::null_mut()
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
128 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
129 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
130 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
131
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
132 /// Generic version of response data.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
133 ///
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
134 /// This has the same structure as [`RawBinaryResponse`]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
135 /// and [`RawTextResponse`].
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
136 #[repr(C)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
137 #[derive(Debug)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
138 pub struct RawResponse {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
139 /// Pointer to the data returned in a response.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
140 /// For most responses, this will be a [`CStr`], but for responses to
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
141 /// [`MessageStyle::BinaryPrompt`]s, this will be [`CBinaryData`]
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
142 /// (a Linux-PAM extension).
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
143 data: *mut c_void,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
144 /// Unused.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
145 return_code: c_int,
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
146 _marker: Immovable,
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
147 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
148
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
149 /// A contiguous block of responses.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
150 #[derive(Debug)]
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
151 pub struct OwnedResponses {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
152 base: *mut RawResponse,
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
153 count: usize,
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
154 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
155
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
156 impl OwnedResponses {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
157 /// Allocates an owned list of responses on the C heap.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
158 fn alloc(count: usize) -> Self {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
159 OwnedResponses {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
160 // SAFETY: We are doing allocation here.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
161 base: unsafe { libc::calloc(count, size_of::<RawResponse>()) }.cast(),
72
47eb242a4f88 Fill out the PamHandle trait.
Paul Fisher <paul@pfish.zone>
parents: 71
diff changeset
162 count,
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
163 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
164 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
165
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
166 pub fn build(value: &[Response]) -> StdResult<Self, FillError> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
167 let mut outputs = OwnedResponses::alloc(value.len());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
168 // If we fail in here after allocating OwnedResponses,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
169 // we still free all memory, even though we don't zero it first.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
170 // This is an acceptable level of risk.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
171 for (input, output) in iter::zip(value.iter(), outputs.iter_mut()) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
172 match input {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
173 Response::NoResponse => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
174 RawTextResponse::fill(output, "")?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
175 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
176 Response::Text(data) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
177 RawTextResponse::fill(output, data)?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
178 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
179 Response::MaskedText(data) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
180 RawTextResponse::fill(output, data.unsecure())?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
181 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
182 Response::Binary(data) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
183 RawBinaryResponse::fill(output, data.data(), data.data_type())?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
184 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
185 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
186 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
187 Ok(outputs)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
188 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
189
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
190 /// Converts this into a `*RawResponse` for passing to PAM.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
191 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
192 /// The pointer "owns" its own data (i.e., this will not be dropped).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
193 pub fn into_ptr(self) -> *mut RawResponse {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
194 let ret = self.base;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
195 mem::forget(self);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
196 ret
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
197 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
198
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
199 /// Takes ownership of a list of responses allocated on the C heap.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
200 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
201 /// # Safety
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
202 ///
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
203 /// It's up to you to make sure you pass a valid pointer.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
204 pub unsafe fn from_c_heap(base: *mut RawResponse, count: usize) -> Self {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
205 OwnedResponses { base, count }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
206 }
66
a674799a5cd3 Make `PamHandle` and `PamModuleHandle` traits.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
207 }
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
208
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
209 #[derive(Debug, thiserror::Error)]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
210 #[error("error converting responses: {0}")]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
211 pub enum FillError {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
212 NulError(#[from] NulError),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
213 TooBigError(#[from] TooBigError),
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
214 }
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
215
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
216 impl Deref for OwnedResponses {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
217 type Target = [RawResponse];
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
218 fn deref(&self) -> &Self::Target {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
219 // SAFETY: This is the memory we manage ourselves.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
220 unsafe { slice::from_raw_parts(self.base, self.count) }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
221 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
222 }
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
223
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
224 impl DerefMut for OwnedResponses {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
225 fn deref_mut(&mut self) -> &mut Self::Target {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
226 // SAFETY: This is the memory we manage ourselves.
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
227 unsafe { slice::from_raw_parts_mut(self.base, self.count) }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
228 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
229 }
66
a674799a5cd3 Make `PamHandle` and `PamModuleHandle` traits.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
230
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
231 impl Drop for OwnedResponses {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
232 fn drop(&mut self) {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
233 // SAFETY: We allocated this ourselves, or it was provided to us by PAM.
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
234 unsafe {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
235 for resp in self.iter_mut() {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
236 libc::free(resp.data)
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
237 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
238 libc::free(self.base.cast())
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
239 }
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
240 }
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
241 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
242
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
243 #[cfg(test)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
244 mod tests {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
245 use super::{BinaryData, OwnedResponses, RawBinaryResponse, RawTextResponse, Response};
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
246
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
247 #[test]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
248 fn test_round_trip() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
249 let responses = [
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
250 Response::Binary(BinaryData::new(vec![1, 2, 3], 99)),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
251 Response::Text("whats going on".to_owned()),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
252 Response::MaskedText("well then".into()),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
253 Response::NoResponse,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
254 Response::Text("bogus".to_owned()),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
255 ];
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
256 let sent = OwnedResponses::build(&responses).unwrap();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
257 let heap_resps = sent.into_ptr();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
258 let mut received = unsafe { OwnedResponses::from_c_heap(heap_resps, 5) };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
259
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
260 let assert_text = |want, raw| {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
261 let up = unsafe { RawTextResponse::upcast(raw) };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
262 assert_eq!(want, up.contents().unwrap());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
263 up.free_contents();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
264 assert_eq!("", up.contents().unwrap());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
265 };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
266 let assert_bin = |want_data: &[u8], want_type, raw| {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
267 let up = unsafe { RawBinaryResponse::upcast(raw) };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
268 assert_eq!(want_data, up.data());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
269 assert_eq!(want_type, up.data_type());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
270 up.free_contents();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
271 let empty: [u8; 0] = [];
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
272 assert_eq!(&empty, up.data());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
273 assert_eq!(0, up.data_type());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
274 };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
275 if let [zero, one, two, three, four] = &mut received[..] {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
276 assert_bin(&[1, 2, 3], 99, zero);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
277 assert_text("whats going on", one);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
278 assert_text("well then", two);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
279 assert_text("", three);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
280 assert_text("bogus", four);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
281 } else {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
282 panic!("wrong size!")
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
283 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
284 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
285
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
286 #[test]
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
287 fn test_text_response() {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
288 let mut responses = OwnedResponses::alloc(2);
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
289 let text = RawTextResponse::fill(&mut responses[0], "hello").unwrap();
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
290 let data = text.contents().expect("valid");
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
291 assert_eq!("hello", data);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
292 text.free_contents();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
293 text.free_contents();
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
294 RawTextResponse::fill(&mut responses[1], "hell\0").expect_err("should error; contains nul");
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
295 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
296
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
297 #[test]
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
298 fn test_binary_response() {
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
299 let mut responses = OwnedResponses::alloc(1);
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
300 let real_data = [1, 2, 3, 4, 5, 6, 7, 8];
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
301 let resp = RawBinaryResponse::fill(&mut responses[0], &real_data, 7)
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
302 .expect("alloc should succeed");
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
303 let data = resp.data();
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
304 assert_eq!(&real_data, data);
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
305 assert_eq!(7, resp.data_type());
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
306 resp.free_contents();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
307 resp.free_contents();
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
308 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
309
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
310 #[test]
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
311 #[ignore]
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
312 fn test_binary_response_too_big() {
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
313 let big_data: Vec<u8> = vec![0xFFu8; 10_000_000_000];
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
314 let mut responses = OwnedResponses::alloc(1);
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
315 RawBinaryResponse::fill(&mut responses[0], &big_data, 0).expect_err("this is too big!");
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
316 }
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 66
diff changeset
317 }