Skip to content

Commit 85b17d4

Browse files
committed
Auto merge of rust-lang#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.
2 parents 24ef42a + 8ca1146 commit 85b17d4

File tree

1 file changed

+18
-10
lines changed
  • src/tools/rust-analyzer/lib/lsp-server/src

1 file changed

+18
-10
lines changed

src/tools/rust-analyzer/lib/lsp-server/src/msg.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ pub struct Notification {
153153
pub params: serde_json::Value,
154154
}
155155

156+
fn invalid_data(error: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
157+
io::Error::new(io::ErrorKind::InvalidData, error)
158+
}
159+
160+
macro_rules! invalid_data {
161+
($($tt:tt)*) => (invalid_data(format!($($tt)*)))
162+
}
163+
156164
impl Message {
157165
pub fn read(r: &mut impl BufRead) -> io::Result<Option<Message>> {
158166
Message::_read(r)
@@ -162,7 +170,14 @@ impl Message {
162170
None => return Ok(None),
163171
Some(text) => text,
164172
};
165-
let msg = serde_json::from_str(&text)?;
173+
174+
let msg = match serde_json::from_str(&text) {
175+
Ok(msg) => msg,
176+
Err(e) => {
177+
return Err(invalid_data!("malformed LSP payload: {:?}", e));
178+
}
179+
};
180+
166181
Ok(Some(msg))
167182
}
168183
pub fn write(self, w: &mut impl Write) -> io::Result<()> {
@@ -240,13 +255,6 @@ impl Notification {
240255
}
241256

242257
fn read_msg_text(inp: &mut dyn BufRead) -> io::Result<Option<String>> {
243-
fn invalid_data(error: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
244-
io::Error::new(io::ErrorKind::InvalidData, error)
245-
}
246-
macro_rules! invalid_data {
247-
($($tt:tt)*) => (invalid_data(format!($($tt)*)))
248-
}
249-
250258
let mut size = None;
251259
let mut buf = String::new();
252260
loop {
@@ -264,12 +272,12 @@ fn read_msg_text(inp: &mut dyn BufRead) -> io::Result<Option<String>> {
264272
let mut parts = buf.splitn(2, ": ");
265273
let header_name = parts.next().unwrap();
266274
let header_value =
267-
parts.next().ok_or_else(|| invalid_data(format!("malformed header: {:?}", buf)))?;
275+
parts.next().ok_or_else(|| invalid_data!("malformed header: {:?}", buf))?;
268276
if header_name.eq_ignore_ascii_case("Content-Length") {
269277
size = Some(header_value.parse::<usize>().map_err(invalid_data)?);
270278
}
271279
}
272-
let size: usize = size.ok_or_else(|| invalid_data("no Content-Length".to_owned()))?;
280+
let size: usize = size.ok_or_else(|| invalid_data!("no Content-Length"))?;
273281
let mut buf = buf.into_bytes();
274282
buf.resize(size, 0);
275283
inp.read_exact(&mut buf)?;

0 commit comments

Comments
 (0)