mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Auto merge of #17207 - Wilfred:serde_invalid_data, r=lnicola
fix: Report all LSP protocol errors with invalid_data Previously we did not use invalid_data for serde errors, making it harder to understand errors when the client sends malformed data to the server.
This commit is contained in:
commit
7d1b3a6607
@ -153,6 +153,14 @@ pub struct Notification {
|
|||||||
pub params: serde_json::Value,
|
pub params: serde_json::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn invalid_data(error: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
|
||||||
|
io::Error::new(io::ErrorKind::InvalidData, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! invalid_data {
|
||||||
|
($($tt:tt)*) => (invalid_data(format!($($tt)*)))
|
||||||
|
}
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
pub fn read(r: &mut impl BufRead) -> io::Result<Option<Message>> {
|
pub fn read(r: &mut impl BufRead) -> io::Result<Option<Message>> {
|
||||||
Message::_read(r)
|
Message::_read(r)
|
||||||
@ -162,7 +170,14 @@ impl Message {
|
|||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
Some(text) => text,
|
Some(text) => text,
|
||||||
};
|
};
|
||||||
let msg = serde_json::from_str(&text)?;
|
|
||||||
|
let msg = match serde_json::from_str(&text) {
|
||||||
|
Ok(msg) => msg,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(invalid_data!("malformed LSP payload: {:?}", e));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Some(msg))
|
Ok(Some(msg))
|
||||||
}
|
}
|
||||||
pub fn write(self, w: &mut impl Write) -> io::Result<()> {
|
pub fn write(self, w: &mut impl Write) -> io::Result<()> {
|
||||||
@ -240,13 +255,6 @@ impl Notification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_msg_text(inp: &mut dyn BufRead) -> io::Result<Option<String>> {
|
fn read_msg_text(inp: &mut dyn BufRead) -> io::Result<Option<String>> {
|
||||||
fn invalid_data(error: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
|
|
||||||
io::Error::new(io::ErrorKind::InvalidData, error)
|
|
||||||
}
|
|
||||||
macro_rules! invalid_data {
|
|
||||||
($($tt:tt)*) => (invalid_data(format!($($tt)*)))
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut size = None;
|
let mut size = None;
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
loop {
|
loop {
|
||||||
@ -264,12 +272,12 @@ fn read_msg_text(inp: &mut dyn BufRead) -> io::Result<Option<String>> {
|
|||||||
let mut parts = buf.splitn(2, ": ");
|
let mut parts = buf.splitn(2, ": ");
|
||||||
let header_name = parts.next().unwrap();
|
let header_name = parts.next().unwrap();
|
||||||
let header_value =
|
let header_value =
|
||||||
parts.next().ok_or_else(|| invalid_data(format!("malformed header: {:?}", buf)))?;
|
parts.next().ok_or_else(|| invalid_data!("malformed header: {:?}", buf))?;
|
||||||
if header_name.eq_ignore_ascii_case("Content-Length") {
|
if header_name.eq_ignore_ascii_case("Content-Length") {
|
||||||
size = Some(header_value.parse::<usize>().map_err(invalid_data)?);
|
size = Some(header_value.parse::<usize>().map_err(invalid_data)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let size: usize = size.ok_or_else(|| invalid_data("no Content-Length".to_owned()))?;
|
let size: usize = size.ok_or_else(|| invalid_data!("no Content-Length"))?;
|
||||||
let mut buf = buf.into_bytes();
|
let mut buf = buf.into_bytes();
|
||||||
buf.resize(size, 0);
|
buf.resize(size, 0);
|
||||||
inp.read_exact(&mut buf)?;
|
inp.read_exact(&mut buf)?;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user