Mercurial > crates > nonstick
annotate src/libpam/memory.rs @ 139:33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
- Uses the libpam-sys-helpers BinaryPayload / OwnedBinaryPayload structs
to handle memory management and parsing for Linux-PAM binary messages.
- Gets rid of the (technically) undefined behavior in PtrPtrVec
due to pointer provenance.
- Don't check for malloc failing. It won't, even if it does.
- Formatting/cleanups/etc.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 03 Jul 2025 23:57:49 -0400 |
parents | 49d9e2b5c189 |
children | a508a69c068a |
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 |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
3 use crate::ErrorCode; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
4 use crate::Result; |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
5 use libpam_sys_helpers::memory::{Buffer, OwnedBinaryPayload}; |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
6 use std::ffi::{c_char, CStr, CString}; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
7 use std::marker::{PhantomData, PhantomPinned}; |
106
49d9e2b5c189
An irresponsible mix of implementing libpam-sys and other stuff.
Paul Fisher <paul@pfish.zone>
parents:
105
diff
changeset
|
8 use std::mem::ManuallyDrop; |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
9 use std::ops::{Deref, DerefMut}; |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
10 use std::ptr::NonNull; |
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
11 use std::{mem, ptr, slice}; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
12 |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
13 /// Allocates `count` elements to hold `T`. |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
14 #[inline] |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
15 pub fn calloc<T>(count: usize) -> NonNull<T> { |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
16 // SAFETY: it's always safe to allocate! Leaking memory is fun! |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
17 unsafe { NonNull::new_unchecked(libc::calloc(count, mem::size_of::<T>()).cast()) } |
78
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
18 } |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
19 |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
20 /// Wrapper for [`libc::free`] to make debugging calls/frees easier. |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
21 /// |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
22 /// # Safety |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
23 /// |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
24 /// If you double-free, it's all your fault. |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
25 #[inline] |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
26 pub unsafe fn free<T>(p: *mut T) { |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
27 libc::free(p.cast()) |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
28 } |
002adfb98c5c
Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents:
77
diff
changeset
|
29 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
30 /// 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
|
31 #[repr(C)] |
80
5aa1a010f1e8
Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents:
79
diff
changeset
|
32 #[derive(Debug, Default)] |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
33 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
|
34 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
35 /// 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
|
36 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
|
37 prompt |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
38 .map(CString::new) |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
39 .transpose() |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
40 .map_err(|_| ErrorCode::ConversationError) |
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 |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
43 /// 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
|
44 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
|
45 match prompt { |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
46 Some(c_str) => c_str.as_ptr(), |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
47 None => ptr::null(), |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
48 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
49 } |
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
50 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
51 /// It's like a [`Box`], but C heap managed. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
52 #[derive(Debug)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
53 #[repr(transparent)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
54 pub struct CHeapBox<T>(NonNull<T>); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
55 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
56 // Lots of "as" and "into" associated functions. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
57 #[allow(clippy::wrong_self_convention)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
58 impl<T> CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
59 /// Creates a new CHeapBox holding the given data. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
60 pub fn new(value: T) -> Result<Self> { |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
61 let memory = calloc(1); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
62 unsafe { ptr::write(memory.as_ptr(), value) } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
63 // SAFETY: We literally just allocated this. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
64 Ok(Self(memory)) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
65 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
66 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
67 /// Takes ownership of the given pointer. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
68 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
69 /// # Safety |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
70 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
71 /// You have to provide a valid pointer to the start of an allocation |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
72 /// that was made with `malloc`. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
73 pub unsafe fn from_ptr(ptr: NonNull<T>) -> Self { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
74 Self(ptr) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
75 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
76 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
77 /// Converts this CBox into a raw pointer. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
78 pub fn into_ptr(this: Self) -> NonNull<T> { |
100
3f11b8d30f63
Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents:
98
diff
changeset
|
79 ManuallyDrop::new(this).0 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
80 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
81 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
82 /// Gets a pointer from this but doesn't convert this into a raw pointer. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
83 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
84 /// You are responsible for ensuring the CHeapBox lives long enough. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
85 pub fn as_ptr(this: &Self) -> NonNull<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
86 this.0 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
87 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
88 |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
89 /// Because it's annoying to type `CHeapBox.as_ptr(...).as_ptr()`. |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
90 pub fn as_raw_ptr(this: &Self) -> *mut T { |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
91 this.0.as_ptr() |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
92 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
93 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
94 /// Converts this into a Box of a different type. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
95 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
96 /// # Safety |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
97 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
98 /// The different type has to be compatible in size/alignment and drop behavior. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
99 pub unsafe fn cast<R>(this: Self) -> CHeapBox<R> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
100 mem::transmute(this) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
101 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
102 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
103 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
104 impl<T: Default> Default for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
105 fn default() -> Self { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
106 Self::new(Default::default()).expect("allocation should not fail") |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
107 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
108 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
109 |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
110 impl Buffer for CHeapBox<u8> { |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
111 fn allocate(len: usize) -> Self { |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
112 // SAFETY: This is all freshly-allocated memory! |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
113 unsafe { Self::from_ptr(calloc(len)) } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
114 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
115 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
116 fn as_ptr(this: &Self) -> *const u8 { |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
117 this.0.as_ptr() |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
118 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
119 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
120 unsafe fn as_mut_slice(this: &mut Self, len: usize) -> &mut [u8] { |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
121 slice::from_raw_parts_mut(this.0.as_ptr(), len) |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
122 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
123 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
124 fn into_ptr(this: Self) -> NonNull<u8> { |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
125 CHeapBox::into_ptr(this) |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
126 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
127 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
128 unsafe fn from_ptr(ptr: NonNull<u8>, _: usize) -> Self { |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
129 CHeapBox::from_ptr(ptr) |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
130 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
131 } |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
132 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
133 pub type CHeapPayload = OwnedBinaryPayload<CHeapBox<u8>>; |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
134 |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
135 impl<T> Deref for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
136 type Target = T; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
137 fn deref(&self) -> &Self::Target { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
138 // SAFETY: We own this pointer and it is guaranteed valid. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
139 unsafe { Self::as_ptr(self).as_ref() } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
140 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
141 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
142 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
143 impl<T> DerefMut for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
144 fn deref_mut(&mut self) -> &mut Self::Target { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
145 // SAFETY: We own this pointer and it is guaranteed valid. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
146 unsafe { Self::as_ptr(self).as_mut() } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
147 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
148 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
149 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
150 impl<T> Drop for CHeapBox<T> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
151 fn drop(&mut self) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
152 // SAFETY: We own a valid pointer, and will never use it after this. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
153 unsafe { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
154 let ptr = self.0.as_ptr(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
155 ptr::drop_in_place(ptr); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
156 free(ptr) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
157 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
158 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
159 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
160 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
161 /// A null-terminated string allocated on the C heap. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
162 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
163 /// Basically [`CString`], but managed by malloc. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
164 #[derive(Debug)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
165 #[repr(transparent)] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
166 pub struct CHeapString(CHeapBox<c_char>); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
167 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
168 impl CHeapString { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
169 /// Creates a new C heap string with the given contents. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
170 pub fn new(text: &str) -> Result<Self> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
171 let data = text.as_bytes(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
172 if data.contains(&0) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
173 return Err(ErrorCode::ConversationError); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
174 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
175 // +1 for the null terminator |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
176 let data_alloc: NonNull<c_char> = calloc(data.len() + 1); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
177 // SAFETY: we just allocated this and we have enough room. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
178 unsafe { |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
179 let dest = slice::from_raw_parts_mut(data_alloc.as_ptr().cast(), data.len()); |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
180 dest.copy_from_slice(data); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
181 Ok(Self(CHeapBox::from_ptr(data_alloc))) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
182 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
183 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
184 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
185 /// Converts this C heap string into a raw pointer. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
186 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
187 /// You are responsible for freeing it later. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
188 pub fn into_ptr(self) -> NonNull<c_char> { |
100
3f11b8d30f63
Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents:
98
diff
changeset
|
189 let this = ManuallyDrop::new(self); |
3f11b8d30f63
Implement environment variable management.
Paul Fisher <paul@pfish.zone>
parents:
98
diff
changeset
|
190 CHeapBox::as_ptr(&this.0) |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
191 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
192 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
193 /// Converts this into a dumb box. It will no longer be zeroed upon drop. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
194 pub fn into_box(self) -> CHeapBox<c_char> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
195 unsafe { mem::transmute(self) } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
196 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
197 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
198 /// Takes ownership of a C heap string. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
199 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
200 /// # Safety |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
201 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
202 /// You have to provide a pointer to the start of an allocation that is |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
203 /// a valid 0-terminated C string. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
204 unsafe fn from_ptr(ptr: *mut c_char) -> Option<Self> { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
205 NonNull::new(ptr).map(|p| unsafe { Self(CHeapBox::from_ptr(p)) }) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
206 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
207 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
208 unsafe fn from_box<T>(bx: CHeapBox<T>) -> Self { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
209 Self(CHeapBox::cast(bx)) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
210 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
211 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
212 /// Zeroes the contents of a C string. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
213 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
214 /// # Safety |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
215 /// |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
216 /// You have to provide a valid pointer to a null-terminated C string. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
217 pub unsafe fn zero(ptr: NonNull<c_char>) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
218 let cstr = ptr.as_ptr(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
219 let len = libc::strlen(cstr.cast()); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
220 for x in 0..len { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
221 ptr::write_volatile(cstr.byte_offset(x as isize), mem::zeroed()) |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
222 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
223 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
224 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
225 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
226 impl Drop for CHeapString { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
227 fn drop(&mut self) { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
228 // SAFETY: We own a valid C String |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
229 unsafe { Self::zero(CHeapBox::as_ptr(&self.0)) } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
230 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
231 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
232 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
233 impl Deref for CHeapString { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
234 type Target = CStr; |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
235 |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
236 fn deref(&self) -> &Self::Target { |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
237 // SAFETY: We know we own a valid C string pointer. |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
238 let ptr = CHeapBox::as_ptr(&self.0).as_ptr(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
239 unsafe { CStr::from_ptr(ptr) } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
240 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
241 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
242 |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
243 /// 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
|
244 /// <code>pam_get_<var>whatever</var></code> function. |
72 | 245 /// |
246 /// # Safety | |
247 /// | |
248 /// It's on you to provide a valid string. | |
95
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
249 pub unsafe fn copy_pam_string(result_ptr: *const c_char) -> Result<Option<String>> { |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
250 let borrowed = match NonNull::new(result_ptr.cast_mut()) { |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
251 Some(data) => Some( |
93
efc2b56c8928
Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents:
80
diff
changeset
|
252 CStr::from_ptr(data.as_ptr()) |
72 | 253 .to_str() |
254 .map_err(|_| ErrorCode::ConversationError)?, | |
95
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
255 ), |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
256 None => return Ok(None), |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
257 }; |
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
258 Ok(borrowed.map(String::from)) |
72 | 259 } |
260 | |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
261 #[cfg(test)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
262 mod tests { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
263 use super::*; |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
264 use std::cell::Cell; |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
265 #[test] |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
266 fn test_box() { |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
267 let drop_count: Cell<u32> = Cell::new(0); |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
268 |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
269 struct Dropper<'a>(&'a Cell<u32>); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
270 |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
271 impl Drop for Dropper<'_> { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
272 fn drop(&mut self) { |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
273 self.0.set(self.0.get() + 1) |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
274 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
275 } |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
276 |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
277 let mut dropbox = CHeapBox::new(Dropper(&drop_count)).unwrap(); |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
278 _ = dropbox; |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
279 // ensure the old value is dropped when the new one is assigned. |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
280 dropbox = CHeapBox::new(Dropper(&drop_count)).unwrap(); |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
281 assert_eq!(1, drop_count.get()); |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
282 *dropbox = Dropper(&drop_count); |
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
283 assert_eq!(2, drop_count.get()); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
284 drop(dropbox); |
139
33b9622ed6d2
Remove redundant memory management in nonstick::libpam; fix UB.
Paul Fisher <paul@pfish.zone>
parents:
106
diff
changeset
|
285 assert_eq!(3, drop_count.get()); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
286 } |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
287 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
288 fn test_strings() { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
289 let str = CHeapString::new("hello there").unwrap(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
290 let str_ptr = str.into_ptr().as_ptr(); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
291 CHeapString::new("hell\0 there").unwrap_err(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
292 unsafe { |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
293 let copied = copy_pam_string(str_ptr).unwrap(); |
95
51c9d7e8261a
Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents:
93
diff
changeset
|
294 assert_eq!("hello there", copied.unwrap()); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
295 CHeapString::zero(NonNull::new(str_ptr).unwrap()); |
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
296 let idx_three = str_ptr.add(3).as_mut().unwrap(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
297 *idx_three = 0x80u8 as i8; |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
298 let zeroed = copy_pam_string(str_ptr).unwrap().unwrap(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
299 assert!(zeroed.is_empty()); |
98
b87100c5eed4
Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents:
95
diff
changeset
|
300 let _ = CHeapString::from_ptr(str_ptr); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
301 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
302 } |
72 | 303 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
304 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
305 fn test_option_str() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
306 let good = option_cstr(Some("whatever")).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
307 assert_eq!("whatever", good.unwrap().to_str().unwrap()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
308 let no_str = option_cstr(None).unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
309 assert!(no_str.is_none()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
310 let bad_str = option_cstr(Some("what\0ever")).unwrap_err(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
311 assert_eq!(ErrorCode::ConversationError, bad_str); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
312 } |
72 | 313 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
314 #[test] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
315 fn test_prompt() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
316 let prompt_cstr = CString::new("good").ok(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
317 let prompt = prompt_ptr(prompt_cstr.as_ref()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
318 assert!(!prompt.is_null()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
319 let no_prompt = prompt_ptr(None); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
320 assert!(no_prompt.is_null()); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
321 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
322 } |