mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-27 15:51:02 +00:00
fix(core/rust): more careful management of ShortString capacity
This commit is contained in:
parent
8cf039740f
commit
4e788aa2f5
@ -2,7 +2,6 @@ use crate::{
|
||||
strutil::ShortString,
|
||||
ui::{component::EventCtx, util::ResultExt},
|
||||
};
|
||||
use heapless::String;
|
||||
|
||||
/// Reified editing operations of `TextBox`.
|
||||
///
|
||||
@ -22,14 +21,15 @@ pub struct TextBox {
|
||||
|
||||
impl TextBox {
|
||||
/// Create a new `TextBox` with content `text`.
|
||||
pub fn new(text: &str) -> Self {
|
||||
let text = unwrap!(String::try_from(text));
|
||||
pub fn new(text: &str, max_len: usize) -> Self {
|
||||
let text = unwrap!(ShortString::try_from(text));
|
||||
debug_assert!(text.capacity() >= max_len);
|
||||
Self { text }
|
||||
}
|
||||
|
||||
/// Create an empty `TextBox`.
|
||||
pub fn empty() -> Self {
|
||||
Self::new("")
|
||||
pub fn empty(max_len: usize) -> Self {
|
||||
Self::new("", max_len)
|
||||
}
|
||||
|
||||
pub fn content(&self) -> &str {
|
||||
|
@ -176,7 +176,7 @@ impl Bip39Input {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
button: Button::empty(),
|
||||
textbox: TextBox::empty(),
|
||||
textbox: TextBox::empty(MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
options_num: None,
|
||||
suggested_word: None,
|
||||
@ -193,7 +193,7 @@ impl Bip39Input {
|
||||
// Styling the input to reflect already filled word
|
||||
Self {
|
||||
button: Button::empty().styled(theme::button_recovery_confirm()),
|
||||
textbox: TextBox::new(word),
|
||||
textbox: TextBox::new(word, MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
options_num: bip39::options_num(word),
|
||||
suggested_word: bip39::complete_word(word),
|
||||
|
@ -414,7 +414,7 @@ impl Input {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
area: Rect::zero(),
|
||||
textbox: TextBox::empty(),
|
||||
textbox: TextBox::empty(MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
use core::mem;
|
||||
use heapless::String;
|
||||
|
||||
use crate::{
|
||||
strutil::{ShortString, TString},
|
||||
@ -294,7 +293,7 @@ impl PinDots {
|
||||
area: Rect::zero(),
|
||||
pad: Pad::with_background(style.background_color),
|
||||
style,
|
||||
digits: String::new(),
|
||||
digits: ShortString::new(),
|
||||
display_digits: false,
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
use core::iter;
|
||||
|
||||
use heapless::String;
|
||||
|
||||
use crate::{
|
||||
strutil::ShortString,
|
||||
trezorhal::slip39,
|
||||
@ -204,7 +202,7 @@ impl Slip39Input {
|
||||
Self {
|
||||
// Button has the same style the whole time
|
||||
button: Button::empty().styled(theme::button_recovery_confirm()),
|
||||
textbox: TextBox::empty(),
|
||||
textbox: TextBox::empty(MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
final_word: None,
|
||||
input_mask: Slip39Mask::full(),
|
||||
@ -222,7 +220,7 @@ impl Slip39Input {
|
||||
Self {
|
||||
// Button has the same style the whole time
|
||||
button: Button::empty().styled(theme::button_recovery_confirm()),
|
||||
textbox: TextBox::new(&buff),
|
||||
textbox: TextBox::new(&buff, MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
final_word,
|
||||
input_mask,
|
||||
|
@ -11,8 +11,6 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use heapless::String;
|
||||
|
||||
use super::super::{
|
||||
theme, ButtonDetails, ButtonLayout, CancelConfirmMsg, ChangingTextLine, ChoiceFactory,
|
||||
ChoiceItem, ChoicePage,
|
||||
@ -286,19 +284,24 @@ impl PassphraseEntry {
|
||||
passphrase_dots: Child::new(ChangingTextLine::center_mono("", MAX_PASSPHRASE_LENGTH)),
|
||||
show_plain_passphrase: false,
|
||||
show_last_digit: false,
|
||||
textbox: TextBox::empty(),
|
||||
textbox: TextBox::empty(MAX_PASSPHRASE_LENGTH),
|
||||
current_category: ChoiceCategory::Menu,
|
||||
}
|
||||
}
|
||||
|
||||
fn update_passphrase_dots(&mut self, ctx: &mut EventCtx) {
|
||||
debug_assert!({
|
||||
let s = ShortString::new();
|
||||
s.capacity() >= MAX_PASSPHRASE_LENGTH
|
||||
});
|
||||
|
||||
let text_to_show = if self.show_plain_passphrase {
|
||||
unwrap!(String::try_from(self.passphrase()))
|
||||
unwrap!(ShortString::try_from(self.passphrase()))
|
||||
} else if self.is_empty() {
|
||||
unwrap!(String::try_from(""))
|
||||
unwrap!(ShortString::try_from(""))
|
||||
} else {
|
||||
// Showing asterisks and possibly the last digit.
|
||||
let mut dots: ShortString = String::new();
|
||||
let mut dots = ShortString::new();
|
||||
for _ in 0..self.textbox.len() - 1 {
|
||||
unwrap!(dots.push('*'));
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ use super::super::{
|
||||
theme, ButtonDetails, ButtonLayout, CancelConfirmMsg, ChangingTextLine, ChoiceFactory,
|
||||
ChoiceItem, ChoicePage,
|
||||
};
|
||||
use heapless::String;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum PinAction {
|
||||
@ -179,7 +178,7 @@ impl<'a> PinEntry<'a> {
|
||||
showing_real_prompt,
|
||||
show_real_pin: false,
|
||||
show_last_digit: false,
|
||||
textbox: TextBox::empty(),
|
||||
textbox: TextBox::empty(MAX_PIN_LENGTH),
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,15 +191,19 @@ impl<'a> PinEntry<'a> {
|
||||
/// Show updated content in the changing line.
|
||||
/// Many possibilities, according to the PIN state.
|
||||
fn update_pin_line(&mut self, ctx: &mut EventCtx) {
|
||||
debug_assert!({
|
||||
let s = ShortString::new();
|
||||
s.capacity() >= MAX_PIN_LENGTH
|
||||
});
|
||||
let mut used_font = Font::BOLD;
|
||||
let pin_line_text = if self.is_empty() && !self.subprompt.is_empty() {
|
||||
// Showing the subprompt in NORMAL font
|
||||
used_font = Font::NORMAL;
|
||||
self.subprompt.map(|s| unwrap!(String::try_from(s)))
|
||||
self.subprompt.map(|s| unwrap!(ShortString::try_from(s)))
|
||||
} else if self.is_empty() {
|
||||
unwrap!(String::try_from(EMPTY_PIN_STR))
|
||||
unwrap!(ShortString::try_from(EMPTY_PIN_STR))
|
||||
} else if self.show_real_pin {
|
||||
unwrap!(String::try_from(self.pin()))
|
||||
unwrap!(ShortString::try_from(self.pin()))
|
||||
} else {
|
||||
// Showing asterisks and possibly the last digit.
|
||||
let mut dots = ShortString::new();
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::super::{theme, ButtonLayout, ChangingTextLine, ChoiceFactory, ChoiceItem, ChoicePage};
|
||||
use heapless::{String, Vec};
|
||||
use heapless::Vec;
|
||||
|
||||
enum WordlistAction {
|
||||
Letter(char),
|
||||
@ -176,7 +176,7 @@ impl WordlistEntry {
|
||||
.with_carousel(true)
|
||||
.with_initial_page_counter(get_random_position(choices_count)),
|
||||
chosen_letters: Child::new(ChangingTextLine::center_mono(PROMPT, LINE_CAPACITY)),
|
||||
textbox: TextBox::empty(),
|
||||
textbox: TextBox::empty(MAX_WORD_LENGTH),
|
||||
offer_words: false,
|
||||
wordlist_type,
|
||||
can_go_back,
|
||||
@ -196,7 +196,7 @@ impl WordlistEntry {
|
||||
.with_incomplete(true)
|
||||
.with_initial_page_counter(1),
|
||||
chosen_letters: Child::new(ChangingTextLine::center_mono(word, LINE_CAPACITY)),
|
||||
textbox: TextBox::new(word),
|
||||
textbox: TextBox::new(word, MAX_WORD_LENGTH),
|
||||
offer_words: false,
|
||||
wordlist_type,
|
||||
can_go_back,
|
||||
|
@ -210,7 +210,7 @@ impl Bip39Input {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
button: Button::empty(),
|
||||
textbox: TextBox::empty(),
|
||||
textbox: TextBox::empty(MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
options_num: None,
|
||||
suggested_word: None,
|
||||
@ -227,7 +227,7 @@ impl Bip39Input {
|
||||
// Styling the input to reflect already filled word
|
||||
Self {
|
||||
button: Button::with_icon(theme::ICON_LIST_CHECK).styled(theme::button_pin_confirm()),
|
||||
textbox: TextBox::new(word),
|
||||
textbox: TextBox::new(word, MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
options_num: bip39::options_num(word),
|
||||
suggested_word: bip39::complete_word(word),
|
||||
|
@ -337,7 +337,7 @@ impl Input {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
area: Rect::zero(),
|
||||
textbox: TextBox::empty(),
|
||||
textbox: TextBox::empty(MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
use core::{char::MAX, mem};
|
||||
use heapless::String;
|
||||
use core::mem;
|
||||
|
||||
use crate::{
|
||||
strutil::{ShortString, TString},
|
||||
@ -316,11 +315,13 @@ impl PinDots {
|
||||
const TWITCH: i16 = 4;
|
||||
|
||||
fn new(style: TextStyle) -> Self {
|
||||
let digits = ShortString::new();
|
||||
debug_assert!(digits.capacity() >= MAX_LENGTH);
|
||||
Self {
|
||||
area: Rect::zero(),
|
||||
pad: Pad::with_background(style.background_color),
|
||||
style,
|
||||
digits: String::new(),
|
||||
digits,
|
||||
display_digits: false,
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
use core::iter;
|
||||
|
||||
use heapless::String;
|
||||
|
||||
use crate::{
|
||||
strutil::ShortString,
|
||||
trezorhal::slip39,
|
||||
@ -263,7 +261,7 @@ impl Slip39Input {
|
||||
Self {
|
||||
// Button has the same style the whole time
|
||||
button: Button::empty().styled(theme::button_pin_confirm()),
|
||||
textbox: TextBox::empty(),
|
||||
textbox: TextBox::empty(MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
final_word: None,
|
||||
input_mask: Slip39Mask::full(),
|
||||
@ -281,7 +279,7 @@ impl Slip39Input {
|
||||
Self {
|
||||
// Button has the same style the whole time
|
||||
button: Button::empty().styled(theme::button_pin_confirm()),
|
||||
textbox: TextBox::new(&buff),
|
||||
textbox: TextBox::new(&buff, MAX_LENGTH),
|
||||
multi_tap: MultiTapKeyboard::new(),
|
||||
final_word,
|
||||
input_mask,
|
||||
@ -290,6 +288,7 @@ impl Slip39Input {
|
||||
|
||||
fn setup_from_prefilled_word(word: &str) -> (ShortString, Slip39Mask, Option<&'static str>) {
|
||||
let mut buff = ShortString::new();
|
||||
debug_assert!(buff.capacity() >= MAX_LENGTH);
|
||||
|
||||
// Gradually appending encoded key digits to the buffer and checking if
|
||||
// have not already formed a final word.
|
||||
|
@ -9,8 +9,6 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use heapless::String;
|
||||
|
||||
use super::display::Font;
|
||||
|
||||
pub trait ResultExt {
|
||||
@ -129,7 +127,7 @@ pub fn icon_text_center(
|
||||
|
||||
/// Convert char to a ShortString.
|
||||
pub fn char_to_string(ch: char) -> ShortString {
|
||||
let mut s = String::new();
|
||||
let mut s = ShortString::new();
|
||||
unwrap!(s.push(ch));
|
||||
s
|
||||
}
|
||||
@ -137,8 +135,7 @@ pub fn char_to_string(ch: char) -> ShortString {
|
||||
/// Returns text to be fit on one line of a given length.
|
||||
/// When the text is too long to fit, it is truncated with ellipsis
|
||||
/// on the left side.
|
||||
/// Hardcoding 50 (via ShortString) as the length of the returned String -
|
||||
/// there should not be any lines as long as this.
|
||||
/// This assumes no lines are longer than 50 chars (ShortString limit)
|
||||
pub fn long_line_content_with_ellipsis(
|
||||
text: &str,
|
||||
ellipsis: &str,
|
||||
@ -146,7 +143,7 @@ pub fn long_line_content_with_ellipsis(
|
||||
available_width: i16,
|
||||
) -> ShortString {
|
||||
if text_font.text_width(text) <= available_width {
|
||||
unwrap!(String::try_from(text)) // whole text can fit
|
||||
unwrap!(ShortString::try_from(text)) // whole text can fit
|
||||
} else {
|
||||
// Text is longer, showing its right end with ellipsis at the beginning.
|
||||
// Finding out how many additional text characters will fit in,
|
||||
|
Loading…
Reference in New Issue
Block a user