mirror of
https://github.com/wez/wezterm.git
synced 2024-11-22 22:42:48 +03:00
codec: improve error messaging when remote is misconfigured
Work a bit harder to surface that the remote might be outputting stuff to stdout. closes: https://github.com/wez/wezterm/issues/5380
This commit is contained in:
parent
107dd67bf2
commit
e19def7c9a
@ -37,8 +37,8 @@ use wezterm_term::color::ColorPalette;
|
|||||||
use wezterm_term::{Alert, ClipboardSelection, StableRowIndex, TerminalSize};
|
use wezterm_term::{Alert, ClipboardSelection, StableRowIndex, TerminalSize};
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
#[error("Corrupt Response")]
|
#[error("Corrupt Response: {0}")]
|
||||||
pub struct CorruptResponse;
|
pub struct CorruptResponse(String);
|
||||||
|
|
||||||
/// Returns the encoded length of the leb128 representation of value
|
/// Returns the encoded length of the leb128 representation of value
|
||||||
fn encoded_length(value: u64) -> usize {
|
fn encoded_length(value: u64) -> usize {
|
||||||
@ -173,30 +173,39 @@ async fn decode_raw_async<R: Unpin + AsyncRead + std::fmt::Debug>(
|
|||||||
r: &mut R,
|
r: &mut R,
|
||||||
max_serial: Option<u64>,
|
max_serial: Option<u64>,
|
||||||
) -> anyhow::Result<Decoded> {
|
) -> anyhow::Result<Decoded> {
|
||||||
let len = read_u64_async(r).await.context("reading PDU length")?;
|
let len = read_u64_async(r)
|
||||||
|
.await
|
||||||
|
.context("decode_raw_async failed to read PDU length")?;
|
||||||
let (len, is_compressed) = if (len & COMPRESSED_MASK) != 0 {
|
let (len, is_compressed) = if (len & COMPRESSED_MASK) != 0 {
|
||||||
(len & !COMPRESSED_MASK, true)
|
(len & !COMPRESSED_MASK, true)
|
||||||
} else {
|
} else {
|
||||||
(len, false)
|
(len, false)
|
||||||
};
|
};
|
||||||
let serial = read_u64_async(r).await.context("reading PDU serial")?;
|
let serial = read_u64_async(r)
|
||||||
|
.await
|
||||||
|
.context("decode_raw_async failed to read PDU serial")?;
|
||||||
if let Some(max_serial) = max_serial {
|
if let Some(max_serial) = max_serial {
|
||||||
if serial > max_serial && max_serial > 0 {
|
if serial > max_serial && max_serial > 0 {
|
||||||
return Err(CorruptResponse).context("decode_raw");
|
return Err(CorruptResponse(format!(
|
||||||
|
"decode_raw_async: serial {serial} is implausibly large \
|
||||||
|
(bigger than {max_serial})"
|
||||||
|
))
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ident = read_u64_async(r).await.context("reading PDU ident")?;
|
let ident = read_u64_async(r)
|
||||||
|
.await
|
||||||
|
.context("decode_raw_async failed to read PDU ident")?;
|
||||||
let data_len =
|
let data_len =
|
||||||
match (len as usize).overflowing_sub(encoded_length(ident) + encoded_length(serial)) {
|
match (len as usize).overflowing_sub(encoded_length(ident) + encoded_length(serial)) {
|
||||||
(_, true) => {
|
(_, true) => {
|
||||||
anyhow::bail!(
|
return Err(CorruptResponse(format!(
|
||||||
"sizes don't make sense: len:{} serial:{} (enc={}) ident:{} (enc={})",
|
"decode_raw_async: sizes don't make sense: \
|
||||||
len,
|
len:{len} serial:{serial} (enc={}) ident:{ident} (enc={})",
|
||||||
serial,
|
|
||||||
encoded_length(serial),
|
encoded_length(serial),
|
||||||
ident,
|
|
||||||
encoded_length(ident)
|
encoded_length(ident)
|
||||||
);
|
))
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
(data_len, false) => data_len,
|
(data_len, false) => data_len,
|
||||||
};
|
};
|
||||||
@ -210,7 +219,8 @@ async fn decode_raw_async<R: Unpin + AsyncRead + std::fmt::Debug>(
|
|||||||
let mut data = vec![0u8; data_len];
|
let mut data = vec![0u8; data_len];
|
||||||
r.read_exact(&mut data).await.with_context(|| {
|
r.read_exact(&mut data).await.with_context(|| {
|
||||||
format!(
|
format!(
|
||||||
"reading {} bytes of data for PDU of length {} with serial={} ident={}",
|
"decode_raw_async failed to read {} bytes of data \
|
||||||
|
for PDU of length {} with serial={} ident={}",
|
||||||
data_len, len, serial, ident
|
data_len, len, serial, ident
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
@ -1167,21 +1167,24 @@ impl Client {
|
|||||||
} else if err.root_cause().is::<CorruptResponse>() {
|
} else if err.root_cause().is::<CorruptResponse>() {
|
||||||
"Received an implausible and likely corrupt response from \
|
"Received an implausible and likely corrupt response from \
|
||||||
the server. This can happen if the remote host outputs \
|
the server. This can happen if the remote host outputs \
|
||||||
to stdout prior to running commands."
|
to stdout prior to running commands. \
|
||||||
|
Check your shell startup!"
|
||||||
.to_string()
|
.to_string()
|
||||||
} else if err.root_cause().is::<ChannelSendError>() {
|
} else if err.root_cause().is::<ChannelSendError>() {
|
||||||
"Internal channel was closed prior to sending request. \
|
"Internal channel was closed prior to sending request. \
|
||||||
This may indicate that the remote host output invalid data \
|
This may indicate that the remote host output invalid data \
|
||||||
to stdout prior to running the requested command"
|
to stdout prior to running the requested command. \
|
||||||
|
Check your shell startup!"
|
||||||
.to_string()
|
.to_string()
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"Please install the same version of wezterm on both \
|
"Please install the same version of wezterm on both \
|
||||||
the client and server! \
|
the client and server! \
|
||||||
The server reported error '{}' while being asked for its \
|
The server reported error '{err}' while being asked for its \
|
||||||
version. This likely means that the server is older \
|
version. This likely means that the server is older \
|
||||||
than the client.\n",
|
than the client, but it could also happen if the remote \
|
||||||
err
|
host outputs to stdout prior to running commands. \
|
||||||
|
Check your shell startup!",
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
ui.output_str(&msg);
|
ui.output_str(&msg);
|
||||||
|
Loading…
Reference in New Issue
Block a user