bitbox02/ui: inline TrinaryInputParams::to_c_params()
What changed, and why it matters
This is a small internal code cleanup in the BitBox02 firmware's Rust UI layer. It removes a helper function and a generic 'Survive' lifetime wrapper, moving the same string-conversion logic directly into the function that creates a user-input prompt. There is no change to user-visible behavior or to security boundaries.
No action required. Review as normal code-quality refactor.
Security signals we found
No security-relevant behavior change
Refactoring only: code moved, not added or removed functionally
No new unsafe blocks, no new FFI calls, no new parsing/validation
Removal of unused generic lifetime helper
Evidence from the diff
The commit inlines TrinaryInputStringParams::to_c_params() into ui::trinary_input_string() and deletes the unused util::Survive<’a, T> struct. The C parameter struct is now built in the caller, with the title CString still allocated and passed to bitbox02_sys::trinary_input_string_create(), which copies the title in C. The lifetime relationship between the Rust title buffer and the C struct pointer is unchanged in practice; the local title Vec simply outlives the unsafe C call as before. No FFI signatures, trust assumptions, or input validation logic are modified.
Changed components
src/rust/bitbox02/src/ui/types.rssrc/rust/bitbox02/src/ui/ui.rssrc/rust/util/src/lib.rsInspect captured patch +24 / −54
diff --git a/src/rust/bitbox02/src/ui/types.rs b/src/rust/bitbox02/src/ui/types.rs
index 6a16367..4bcd882 100644
--- a/src/rust/bitbox02/src/ui/types.rs
+++ b/src/rust/bitbox02/src/ui/types.rs
@@ -2,9 +2,6 @@
extern crate alloc;
use alloc::boxed::Box;
-use alloc::vec::Vec;
-
-use util::Survive;
pub use bitbox02_sys::trinary_choice_t as TrinaryChoice;
@@ -66,40 +63,6 @@ pub struct TrinaryInputStringParams<'a> {
pub default_to_digits: bool,
}
-impl<'a> TrinaryInputStringParams<'a> {
- #[cfg_attr(any(feature = "testing", feature = "c-unit-testing"), allow(dead_code))]
- pub(crate) fn to_c_params(
- &self,
- title_scratch: &'a mut Vec<core::ffi::c_char>,
- ) -> Survive<'a, bitbox02_sys::trinary_input_string_params_t> {
- // We truncate at a bit higher than MAX_LABEL_SIZE, so the label component will correctly
- // truncate and append '...'.
- const TRUNCATE_SIZE: usize = MAX_LABEL_SIZE + 1;
-
- *title_scratch =
- util::strings::str_to_cstr_vec(util::strings::truncate_str(self.title, TRUNCATE_SIZE))
- .unwrap();
-
- Survive::new(bitbox02_sys::trinary_input_string_params_t {
- title: title_scratch.as_ptr().cast(),
- wordlist: match self.wordlist {
- None => core::ptr::null(),
- Some(wordlist) => wordlist.as_ptr(),
- },
- wordlist_size: match self.wordlist {
- None => 0,
- Some(wordlist) => wordlist.len() as _,
- },
- number_input: self.number_input,
- hide: self.hide,
- special_chars: self.special_chars,
- longtouch: self.longtouch,
- cancel_is_backbutton: self.cancel_is_backbutton,
- default_to_digits: self.default_to_digits,
- })
- }
-}
-
pub type SelectWordCb<'a> = Box<dyn FnMut(u8) + 'a>;
pub type ContinueCancelCb<'a> = Box<dyn FnMut() + 'a>;
diff --git a/src/rust/bitbox02/src/ui/ui.rs b/src/rust/bitbox02/src/ui/ui.rs
index 87f087f..3efb699 100644
--- a/src/rust/bitbox02/src/ui/ui.rs
+++ b/src/rust/bitbox02/src/ui/ui.rs
@@ -103,10 +103,32 @@ pub async fn trinary_input_string(
(None, core::ptr::null_mut())
};
- let mut title_scratch = Vec::new();
+ // We truncate at a bit higher than MAX_LABEL_SIZE, so the label component will correctly
+ // truncate and append '...'.
+ const TRUNCATE_SIZE: usize = super::types::MAX_LABEL_SIZE + 1;
+ let title =
+ util::strings::str_to_cstr_vec(util::strings::truncate_str(params.title, TRUNCATE_SIZE))
+ .unwrap();
+ let c_params = bitbox02_sys::trinary_input_string_params_t {
+ title: title.as_ptr().cast(),
+ wordlist: match params.wordlist {
+ None => core::ptr::null(),
+ Some(wordlist) => wordlist.as_ptr(),
+ },
+ wordlist_size: match params.wordlist {
+ None => 0,
+ Some(wordlist) => wordlist.len() as _,
+ },
+ number_input: params.number_input,
+ hide: params.hide,
+ special_chars: params.special_chars,
+ longtouch: params.longtouch,
+ cancel_is_backbutton: params.cancel_is_backbutton,
+ default_to_digits: params.default_to_digits,
+ };
let component = unsafe {
bitbox02_sys::trinary_input_string_create(
- ¶ms.to_c_params(&mut title_scratch).data, // title copied in C
+ &c_params, // title copied in C
Some(confirm_cb),
shared_state_ptr, // passed to confirm_cb as `user_data`.
actual_cancel_cb,
diff --git a/src/rust/util/src/lib.rs b/src/rust/util/src/lib.rs
index bbf56da..4faa048 100644
--- a/src/rust/util/src/lib.rs
+++ b/src/rust/util/src/lib.rs
@@ -33,21 +33,6 @@ pub fn zero(dst: &mut [u8]) {
}
}
-/// Survive forces T to live at least as long as lifetme 'a.
-pub struct Survive<'a, T: 'a> {
- pub data: T,
- phantom: core::marker::PhantomData<&'a T>,
-}
-
-impl<T> Survive<'_, T> {
- pub fn new(data: T) -> Self {
- Survive {
- data,
- phantom: core::marker::PhantomData,
- }
- }
-}
-
// # C interface
/// Zero a buffer using volatile writes. Accepts null-ptr and 0-length buffers and does nothing.
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.