From 0850ebc9e4d5b66ba214f01b0a058b7f5ca73bfc Mon Sep 17 00:00:00 2001 From: Eyal Kalderon Date: Thu, 3 Mar 2022 21:00:00 -0500 Subject: [PATCH] Return "invalid request" if JSON parses, but isn't a Request --- src/transport.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/transport.rs b/src/transport.rs index d9bbfe49..cca015db 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -1,5 +1,8 @@ //! Generic server for multiplexing bidirectional streams through a transport. +#[cfg(feature = "runtime-agnostic")] +use std::error::Error as StdError; + #[cfg(feature = "runtime-agnostic")] use async_codec_lite::{FramedRead, FramedWrite}; #[cfg(feature = "runtime-agnostic")] @@ -15,7 +18,7 @@ use futures::{future, join, stream, FutureExt, Sink, SinkExt, Stream, StreamExt, use log::error; use tower::Service; -use crate::codec::LanguageServerCodec; +use crate::codec::{LanguageServerCodec, ParseError}; use crate::jsonrpc::{Error, Id, Message, Request, Response}; use crate::service::{ClientSocket, RequestStream, ResponseSink}; @@ -149,7 +152,7 @@ where } Err(err) => { error!("failed to decode message: {}", err); - let res = Response::from_error(Id::Null, Error::parse_error()); + let res = Response::from_error(Id::Null, to_jsonrpc_error(err)); responses_tx.send(Message::Response(res)).await.unwrap(); } } @@ -172,6 +175,24 @@ fn display_sources(error: &dyn std::error::Error) -> String { } } +#[cfg(feature = "runtime-tokio")] +#[inline] +fn to_jsonrpc_error(err: ParseError) -> Error { + match err { + ParseError::Body(err) if err.is_data() => Error::invalid_request(), + _ => Error::parse_error(), + } +} + +#[cfg(feature = "runtime-agnostic")] +#[inline] +fn to_jsonrpc_error(err: impl StdError) -> Error { + match err.source().and_then(|e| e.downcast_ref()) { + Some(ParseError::Body(err)) if err.is_data() => Error::invalid_request(), + _ => Error::parse_error(), + } +} + #[cfg(test)] mod tests { use std::task::{Context, Poll};