From 6bd7487b530e23d99007af0902bca0de7bb27381 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Thu, 12 Nov 2026 00:02:37 +0000 Subject: [PATCH] fix(control): an undecodable request id is rejected --- apps/cadcraft/src/control_server.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/cadcraft/src/control_server.rs b/apps/cadcraft/src/control_server.rs index 02b92ba25..4cde6ef2e 100644 --- a/apps/cadcraft/src/control_server.rs +++ b/apps/cadcraft/src/control_server.rs @@ -266,7 +266,10 @@ fn parse_line(bytes: &[u8]) -> Line<'_> { }; let id = match obj.remove("id") { None => Value::Null, - Some(r) if r.get().len() <= MAX_ID_BYTES => serde_json::from_str(r.get()).unwrap_or(Value::Null), + Some(r) if r.get().len() <= MAX_ID_BYTES => match serde_json::from_str(r.get()) { + Ok(v) => v, + Err(e) => return Line::Reject(format!("bad `id` ({e}); closing the connection")), + }, Some(_) => return Line::Reject(format!("`id` is longer than {MAX_ID_BYTES} bytes; closing the connection")), }; Line::Request { id, method, params: obj.remove("params"), token: string(obj.remove("token")) } @@ -401,6 +404,7 @@ mod tests { assert!(matches!(parse_line(br#"{"id":[1],"method":5}"#), Line::Reject(e) if e.contains("missing string `method`"))); let long_id = format!(r#"{{"id":"{}","method":"m"}}"#, "x".repeat(MAX_ID_BYTES)); assert!(matches!(parse_line(long_id.as_bytes()), Line::Reject(e) if e.contains("`id` is longer"))); + assert!(matches!(parse_line(br#"{"id":"\ud800","method":"m"}"#), Line::Reject(e) if e.contains("bad `id`"))); assert!(matches!(parse_line(br#"{"id":1}"#), Line::Reject(e) if e.contains("missing string `method`"))); }