#![cfg(test)]
use crate::{
connection::{read_connection::ReadConnection, socket::Socket},
test_utils::mock_socket::MockSocket,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(tag = "method", content = "parameters")]
enum TestMethod {
#[serde(rename = "org.example.Test")]
Test { value: u32 },
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct TestReply {
result: String,
}
#[tokio::test]
async fn malformed_json_extremely_long_string() {
let mut malicious = r#"{"method":"org.example.Test","parameters":{"value":"#.to_string();
malicious.push_str(&"A".repeat(10 * 1024 * 1024));
malicious.push_str(r#"}}"#);
let socket = MockSocket::with_responses(&[&malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::Json(_))));
}
#[tokio::test]
async fn malformed_json_deeply_nested_objects() {
let mut malicious = r#"{"method":"org.example.Test","parameters":{"value":"#.to_string();
for _ in 0..10000 {
malicious.push_str(r#"{"a":"#);
}
malicious.push_str("0");
for _ in 0..10000 {
malicious.push('}');
}
malicious.push_str(r#"}}"#);
let socket = MockSocket::with_responses(&[&malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::Json(_))));
}
#[tokio::test]
async fn malformed_json_deeply_nested_arrays() {
let mut malicious = r#"{"method":"org.example.Test","parameters":{"value":"#.to_string();
for _ in 0..10000 {
malicious.push('[');
}
malicious.push_str("0");
for _ in 0..10000 {
malicious.push(']');
}
malicious.push_str(r#"}}"#);
let socket = MockSocket::with_responses(&[&malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::Json(_))));
}
#[tokio::test]
async fn malformed_json_unterminated_string() {
let malicious = r#"{"method":"org.example.Test","parameters":{"value":"#;
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(
result,
Err(crate::Error::Json(_)) | Err(crate::Error::UnexpectedEof)
));
}
#[tokio::test]
async fn malformed_json_unterminated_object() {
let malicious = r#"{"method":"org.example.Test","parameters":{"value":42"#;
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(
result,
Err(crate::Error::Json(_)) | Err(crate::Error::UnexpectedEof)
));
}
#[tokio::test]
async fn malformed_json_invalid_escape_sequences() {
let malicious = r#"{"method":"org.example.Test","parameters":{"value":"\x\x\x\x\x\x"}}"#;
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::Json(_))));
}
#[tokio::test]
async fn malformed_json_invalid_utf8_sequences() {
let malicious = r#"{"method":"org.example.Test","parameters":{"value":"\xFF\xFE\xFD"}}"#;
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::Json(_))));
}
#[tokio::test]
async fn buffer_overflow_near_max_size() {
let size = 10 * 1024 * 1024;
let mut large_msg = r#"{"method":"org.example.Test","parameters":{"value":"#.to_string();
large_msg.push_str(&"X".repeat(size));
large_msg.push_str(r#"}}"#);
let socket = MockSocket::with_responses(&[&large_msg]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(result.is_err());
}
#[tokio::test]
async fn buffer_overflow_exceeds_max_size() {
let size = 50 * 1024 * 1024; let chunk = "X".repeat(size);
let mut large_msg = r#"{"method":"org.example.Test","parameters":{"value":"#.to_string();
large_msg.push_str(&chunk);
large_msg.push_str(&chunk);
large_msg.push_str(&chunk); large_msg.push_str(r#"}}"#);
let socket = MockSocket::with_responses(&[&large_msg]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::BufferOverflow)));
}
#[tokio::test]
async fn missing_null_terminator() {
let valid_msg = r#"{"method":"org.example.Test","parameters":{"value":42}}"#;
let socket = MockSocket::with_responses(&[valid_msg]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(result.is_ok());
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::UnexpectedEof)));
}
#[tokio::test]
async fn multiple_null_bytes_in_message() {
let malicious = "{\0\"method\":\"org.example.Test\"\0}";
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(
result,
Err(crate::Error::Json(_)) | Err(crate::Error::UnexpectedEof)
));
}
#[tokio::test]
async fn stream_deserializer_empty_buffer() {
let malicious = "";
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(result.is_err());
match result {
Err(crate::Error::UnexpectedEof) => {}
Err(crate::Error::Json(_)) => {}
other => panic!("Expected error, got {:?}", other),
}
}
#[tokio::test]
async fn stream_deserializer_whitespace_only() {
let malicious = " \n\n\t\t ";
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(
result,
Err(crate::Error::Json(_)) | Err(crate::Error::UnexpectedEof)
));
}
#[tokio::test]
async fn malformed_json_repeated_keys() {
let mut malicious = r#"{"method":"org.example.Test","parameters":{"#.to_string();
for i in 0..10000 {
malicious.push_str(&format!(r#""key{i}":"value{i}","#));
}
malicious.push_str(r#""value":42}}"#);
let socket = MockSocket::with_responses(&[&malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
if let Err(e) = result {
assert!(matches!(e, crate::Error::Json(_)));
}
}
#[tokio::test]
async fn malformed_json_very_long_array() {
let mut malicious = r#"{"method":"org.example.Test","parameters":{"value":["#.to_string();
for i in 0..100000 {
if i > 0 {
malicious.push(',');
}
malicious.push_str(&i.to_string());
}
malicious.push_str(r#"]}}"#);
let socket = MockSocket::with_responses(&[&malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::Json(_))));
}
#[tokio::test]
async fn byte_offset_calculation_with_valid_json() {
let valid_msg = r#"{"method":"org.example.Test","parameters":{"value":42}}"#;
let socket = MockSocket::with_responses(&[valid_msg]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(result.is_ok());
#[cfg(feature = "std")]
let (call, _fds) = result.unwrap();
#[cfg(not(feature = "std"))]
let call = result.unwrap();
assert_eq!(call.method, TestMethod::Test { value: 42 });
}
#[tokio::test]
async fn byte_offset_calculation_with_trailing_data() {
let valid_msg1 = r#"{"method":"org.example.Test","parameters":{"value":42}}"#;
let valid_msg2 = r#"{"method":"org.example.Test","parameters":{"value":99}}"#;
let socket = MockSocket::with_responses(&[valid_msg1, valid_msg2]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(result.is_ok());
#[cfg(feature = "std")]
let (call, _fds) = result.unwrap();
#[cfg(not(feature = "std"))]
let call = result.unwrap();
assert_eq!(call.method, TestMethod::Test { value: 42 });
let result = conn.receive_call::<TestMethod>().await;
assert!(result.is_ok());
#[cfg(feature = "std")]
let (call, _fds) = result.unwrap();
#[cfg(not(feature = "std"))]
let call = result.unwrap();
assert_eq!(call.method, TestMethod::Test { value: 99 });
}
#[tokio::test]
async fn error_propagation_json_to_error() {
let invalid_json = r#"{"method":"org.example.Test","parameters":{"value":"not_a_number"}}"#;
let socket = MockSocket::with_responses(&[invalid_json]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
match result {
Err(crate::Error::Json(e)) => {
assert!(!e.to_string().is_empty());
}
_ => panic!("Expected Error::Json, got {:?}", result),
}
}
#[tokio::test]
async fn receive_reply_with_malformed_json() {
let malformed = r#"{"parameters":{"result":"incomplete"#;
let socket = MockSocket::with_responses(&[malformed]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_reply::<TestReply, TestReply>().await;
assert!(matches!(
result,
Err(crate::Error::Json(_)) | Err(crate::Error::UnexpectedEof)
));
}
#[tokio::test]
async fn receive_reply_with_large_payload() {
let large_result = "X".repeat(1024 * 1024); let reply = format!(r#"{{"parameters":{{"result":"{}"}}}}"#, large_result);
let socket = MockSocket::with_responses(&[&reply]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_reply::<TestReply, TestReply>().await;
assert!(result.is_ok());
}
#[tokio::test]
async fn malformed_json_mixed_control_characters() {
let malicious = "{\x01\"method\"\x02:\x03\"org.example.Test\"}";
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::Json(_))));
}
#[tokio::test]
async fn malformed_json_number_overflow() {
let malicious = r#"{"method":"org.example.Test","parameters":{"value":999999999999999999999999999999999999999999999999999}}"#;
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::Json(_))));
}
#[tokio::test]
async fn malformed_json_duplicate_keys() {
let malicious =
r#"{"method":"org.example.Test","method":"org.example.Other","parameters":{"value":42}}"#;
let socket = MockSocket::with_responses(&[malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
let _ = result;
}
#[tokio::test]
async fn malformed_json_unicode_escapes() {
let mut malicious = r#"{"method":"org.example.Test","parameters":{"value":"#.to_string();
for _ in 0..10000 {
malicious.push_str(r#"\u0041"#); }
malicious.push_str(r#"}}"#);
let socket = MockSocket::with_responses(&[&malicious]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
let result = conn.receive_call::<TestMethod>().await;
assert!(result.is_err()); }
#[tokio::test]
async fn partial_message_at_buffer_boundary() {
let valid_msg = r#"{"method":"org.example.Test","parameters":{"value":42}}"#;
let socket = MockSocket::with_responses(&[valid_msg]);
let (read, _write) = socket.split();
let mut conn = ReadConnection::new(read, 0);
assert!(conn.receive_call::<TestMethod>().await.is_ok());
let result = conn.receive_call::<TestMethod>().await;
assert!(matches!(result, Err(crate::Error::UnexpectedEof)));
}