use dig_nat::{RangeFrame, RangeRequest};
const STRANGER_MARKER: &str = "PEER-CHOSEN-TEXT-0f9a1c";
fn hostile_frame_wire(text: &str) -> Vec<u8> {
let body = format!(r#"{{"offset":"{text}","length":0,"bytes":"","complete":true}}"#);
let mut wire = Vec::with_capacity(4 + body.len());
wire.extend_from_slice(&(body.len() as u32).to_be_bytes());
wire.extend_from_slice(body.as_bytes());
wire
}
async fn decode_error(wire: Vec<u8>) -> std::io::Error {
let mut cursor = std::io::Cursor::new(wire);
match RangeFrame::decode(&mut cursor).await {
Ok(frame) => panic!("a malformed frame must not decode, got {frame:?}"),
Err(e) => e,
}
}
#[test]
fn serde_json_quotes_the_peer_input_back_verbatim() {
let body = format!(r#"{{"offset":"{STRANGER_MARKER}","length":0,"bytes":"","complete":true}}"#);
let raw = serde_json::from_slice::<RangeFrame>(body.as_bytes())
.expect_err("a string offset is not a u64")
.to_string();
assert!(
raw.contains(STRANGER_MARKER),
"this test's premise is gone: serde no longer echoes the input, so the fix it guards is \
no longer proven by the test below. Got: {raw}"
);
}
#[tokio::test]
async fn peer_bytes_never_reach_the_decode_error() {
let err = decode_error(hostile_frame_wire(STRANGER_MARKER)).await;
let msg = err.to_string();
assert!(
!msg.contains(STRANGER_MARKER),
"the decode error echoed the peer's own bytes back: {msg}"
);
let debug = format!("{err:?}");
assert!(
!debug.contains(STRANGER_MARKER),
"the decode error's Debug echoed the peer's own bytes back: {debug}"
);
}
#[tokio::test]
async fn the_decode_error_still_diagnoses_the_failure() {
let err = decode_error(hostile_frame_wire(STRANGER_MARKER)).await;
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
let msg = err.to_string();
assert!(
msg.contains("line 1") && msg.contains("column"),
"a developer must still be able to locate the failure, got: {msg}"
);
assert!(
msg.contains("data"),
"a developer must still be able to tell a syntax error from a schema error, got: {msg}"
);
}
#[tokio::test]
async fn a_forged_log_line_cannot_be_smuggled_through_a_decode_error() {
let forged = format!("{STRANGER_MARKER}\\n2026-07-31T00:00:00Z ERROR forged");
let err = decode_error(hostile_frame_wire(&forged)).await;
let msg = err.to_string();
assert!(
!msg.contains('\n') && !msg.contains('\r'),
"the decode error carried a line break, so a peer can forge log lines: {msg:?}"
);
assert!(
!msg.contains("forged"),
"the decode error echoed the peer's forged line: {msg:?}"
);
}
#[tokio::test]
async fn a_strangers_request_preamble_cannot_echo_its_own_bytes_back() {
let body = format!(r#"{{"store_id":"{STRANGER_MARKER}","length":"{STRANGER_MARKER}"}}"#);
let mut wire = Vec::new();
wire.extend_from_slice(&(body.len() as u32).to_be_bytes());
wire.extend_from_slice(body.as_bytes());
let mut cursor = std::io::Cursor::new(wire);
let err = RangeRequest::decode(&mut cursor)
.await
.expect_err("a string length is not a u64");
assert!(
!err.to_string().contains(STRANGER_MARKER),
"the serving side echoed the stranger's bytes: {err}"
);
assert!(
!format!("{err:?}").contains(STRANGER_MARKER),
"the serving side's Debug echoed the stranger's bytes: {err:?}"
);
assert!(err.to_string().contains("column"), "got: {err}");
}
use dig_nat::{MethodError, NatError, TraversalKind};
#[test]
fn a_traversal_reason_cannot_forge_a_log_line_through_the_aggregate() {
let hostile = "connection refused\n2026-07-31T00:00:00Z ERROR peer is trustworthy";
let aggregate = NatError::AllMethodsFailed(vec![
MethodError::failed(TraversalKind::Direct, hostile),
MethodError::timeout(TraversalKind::Relayed),
]);
let rendered = aggregate.to_string();
assert!(
!rendered.contains('\n') && !rendered.contains('\r'),
"a peer-influenced reason forged a line break in the aggregate: {rendered:?}"
);
assert!(
rendered.contains("connection refused"),
"the diagnosis was deleted rather than neutralized: {rendered}"
);
assert!(
rendered.contains("Relayed"),
"the other method's failure went missing: {rendered}"
);
}
#[test]
fn a_traversal_reason_is_neutralized_in_display_and_debug() {
let err = MethodError::failed(TraversalKind::Direct, "a\u{202E}b\nc");
for rendered in [err.to_string(), format!("{err:?}")] {
assert!(
!rendered.contains('\n'),
"line break survived: {rendered:?}"
);
assert!(
!rendered.contains('\u{202E}'),
"bidi override survived: {rendered:?}"
);
}
}