dioxus
dioxus copied to clipboard
TUI Input is not UTF-8 safe
Problem
Putting multibyte characters into tui inputs panics whenever the cursor passes over them, as the multibyte character is treated as two cursor positions and trips up in a call to split_at in plasmo.
Steps To Reproduce
Steps to reproduce the behavior:
- create an
inputwith value set to some multibyte character - focus the input
- attempt to move the cursor across the multibyte character, either using the right arrow key or using the end key
use crossterm::{execute, terminal::{disable_raw_mode, LeaveAlternateScreen}};
use dioxus::prelude::*;
use std::io::stdout;
fn main() {
let panic_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |panic| {
reset_term().expect("failed to reset the terminal");
panic_hook(panic);
}));
dioxus_tui::launch(app);
}
fn reset_term() -> std::io::Result<()> {
execute!(stdout(), LeaveAlternateScreen)?;
disable_raw_mode()?;
Ok(())
}
fn app(cx: Scope) -> Element {
cx.render(rsx!{
input {
value: "Hello, world! 🧡",
}
})
}
thread 'main' panicked at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/str/mod.rs:666:13:
byte index 15 is not a char boundary; it is inside '🧡' (bytes 14..18) of `Hello, world! 🧡`
[...]
21: 0x5b2071163047 - core::str::<impl str>::split_at::hf4b04f97915ce27d
at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/str/mod.rs:666:13
22: 0x5b207116b776 - plasmo::widgets::text_like::TextLike<C>::write_value::h146b9797a78959f1
at /home/lmh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/plasmo-0.4.3/src/widgets/text_like.rs:140:13
Environment:
- Dioxus version: 0.4.3
- Rust version: stable
- OS info: all
- App platform: tui
Questionnaire
- [x] I'm interested in fixing this myself but don't know where to start
- [ ] I would like to fix and I have a solution
- [ ] I don't have time to fix this right now, but maybe later
I think Plasmo is trying to treat the character offset as a byte offset when you move the cursor here:
https://github.com/DioxusLabs/dioxus/blob/main/packages/native-core/src/utils/cursor.rs#L113-L114
We need to convert the character offset into a byte offset by reading the length of the characters after or before the current position with char_indicies