fix(client): safe Unicode truncation via trunc(), fixes panic on non-ASCII chars
This commit is contained in:
parent
1823b6021a
commit
27b1ffc55b
1 changed files with 15 additions and 12 deletions
|
|
@ -20,6 +20,17 @@ mod windows_mgmt;
|
||||||
|
|
||||||
// ─── CLI Output ─────────────────────────────────────────────────────────────
|
// ─── CLI Output ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// Truncate a string to at most `max_chars` Unicode characters.
|
||||||
|
fn trunc(s: &str, max_chars: usize) -> String {
|
||||||
|
let mut chars = s.chars();
|
||||||
|
let truncated: String = chars.by_ref().take(max_chars).collect();
|
||||||
|
if chars.next().is_some() {
|
||||||
|
format!("{}…", truncated)
|
||||||
|
} else {
|
||||||
|
truncated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn banner() {
|
fn banner() {
|
||||||
println!();
|
println!();
|
||||||
println!(" {} HELIOS REMOTE v{} ({})", "☀".yellow().bold(), env!("CARGO_PKG_VERSION"), env!("GIT_COMMIT"));
|
println!(" {} HELIOS REMOTE v{} ({})", "☀".yellow().bold(), env!("CARGO_PKG_VERSION"), env!("GIT_COMMIT"));
|
||||||
|
|
@ -365,7 +376,7 @@ async fn handle_message(
|
||||||
let _title = title.unwrap_or_else(|| "Helios Remote".to_string());
|
let _title = title.unwrap_or_else(|| "Helios Remote".to_string());
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let title = _title.clone();
|
let title = _title.clone();
|
||||||
log_cmd!("💬", "prompt › {}", &message[..message.len().min(60)]);
|
log_cmd!("💬", "prompt › {}", trunc(&message, 60));
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
use windows::core::PCWSTR;
|
use windows::core::PCWSTR;
|
||||||
|
|
@ -384,7 +395,7 @@ async fn handle_message(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}).await.ok();
|
}).await.ok();
|
||||||
log_ok!("User confirmed: {}", &msg_clone[..msg_clone.len().min(40)]);
|
log_ok!("User confirmed: {}", trunc(&msg_clone, 40));
|
||||||
}
|
}
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
{
|
{
|
||||||
|
|
@ -395,21 +406,13 @@ async fn handle_message(
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerMessage::ExecRequest { request_id, command, timeout_ms } => {
|
ServerMessage::ExecRequest { request_id, command, timeout_ms } => {
|
||||||
let cmd_display = if command.len() > 60 {
|
let cmd_display = trunc(&command, 60);
|
||||||
format!("{}…", &command[..60])
|
|
||||||
} else {
|
|
||||||
command.clone()
|
|
||||||
};
|
|
||||||
log_cmd!("⚡", "exec › {}", cmd_display);
|
log_cmd!("⚡", "exec › {}", cmd_display);
|
||||||
let mut sh = shell.lock().await;
|
let mut sh = shell.lock().await;
|
||||||
match sh.run(&command, timeout_ms).await {
|
match sh.run(&command, timeout_ms).await {
|
||||||
Ok((stdout, stderr, exit_code)) => {
|
Ok((stdout, stderr, exit_code)) => {
|
||||||
let out = stdout.trim().lines().next().unwrap_or("").to_string();
|
let out = stdout.trim().lines().next().unwrap_or("").to_string();
|
||||||
let out_display = if out.len() > 60 {
|
let out_display = trunc(&out, 60);
|
||||||
format!("{}…", &out[..60])
|
|
||||||
} else {
|
|
||||||
out
|
|
||||||
};
|
|
||||||
if exit_code != 0 {
|
if exit_code != 0 {
|
||||||
if out_display.is_empty() {
|
if out_display.is_empty() {
|
||||||
log_err!("exit {}", exit_code);
|
log_err!("exit {}", exit_code);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue