use super::{reserve_decoded_vec_capacity, LebReader};
use crate::serial::wire::{Reader, MAX_DECODE_DEPTH, MAX_OPAQUE_PAYLOAD_LEN};
#[test]
fn data_type_depth_guard_rejects_nested_vec_chain() {
let bytes = vec![0x14_u8; MAX_DECODE_DEPTH as usize + 4];
let mut reader = Reader {
bytes: &bytes,
pos: 0,
depth: 0,
};
let err = reader
.data_type()
.expect_err("Fix: nested DataType::Vec chain must hit the decode depth guard");
assert!(
err.contains("maximum decode depth"),
"depth-guard error must be actionable: {err}"
);
assert!(
reader.pos <= MAX_DECODE_DEPTH as usize,
"guard must fire before consuming the whole chain: pos={}",
reader.pos
);
}
#[test]
fn reserve_wire_vec_caps_pre_reservation_at_remaining_bytes() {
let bytes = [0_u8; 8];
let reader = Reader {
bytes: &bytes,
pos: 0,
depth: 0,
};
let mut v: Vec<u32> = Vec::new();
reader
.reserve_wire_vec(&mut v, 1_000_000, "node count")
.expect("Fix: capped reservation for a truncated blob must succeed");
assert!(v.is_empty());
assert!(
v.capacity() <= bytes.len(),
"reservation must be capped at remaining bytes, got capacity {}",
v.capacity()
);
}
#[test]
fn wire_decode_reservation_reports_capacity_overflow() {
let mut bytes = Vec::<u8>::new();
let error = reserve_decoded_vec_capacity(&mut bytes, usize::MAX, "test wire bytes")
.expect_err("Fix: impossible wire reserve must fail before allocation.");
assert!(
error.contains("failed to reserve test wire bytes"),
"Fix: wire decode reserve errors must name the field that failed: {error}"
);
}
fn leb_encode_usize(mut value: usize) -> Vec<u8> {
let mut out = Vec::new();
loop {
let mut byte = (value & 0x7F) as u8;
value >>= 7;
if value != 0 {
byte |= 0x80;
}
out.push(byte);
if value == 0 {
break;
}
}
out
}
#[test]
fn node_payload_len_at_limit_is_accepted() {
let encoded = leb_encode_usize(MAX_OPAQUE_PAYLOAD_LEN);
let mut reader = Reader {
bytes: &encoded,
pos: 0,
depth: 0,
};
let result = reader.leb_len(MAX_OPAQUE_PAYLOAD_LEN, "node payload length");
assert!(
result.is_ok(),
"payload_len == MAX_OPAQUE_PAYLOAD_LEN must be accepted: {:?}",
result
);
assert_eq!(result.unwrap(), MAX_OPAQUE_PAYLOAD_LEN);
}
#[test]
fn node_payload_len_exceeds_limit_rejected() {
let over_limit = MAX_OPAQUE_PAYLOAD_LEN + 1;
let encoded = leb_encode_usize(over_limit);
let mut reader = Reader {
bytes: &encoded,
pos: 0,
depth: 0,
};
let err = reader
.leb_len(MAX_OPAQUE_PAYLOAD_LEN, "node payload length")
.expect_err(
"Fix: payload_len beyond MAX_OPAQUE_PAYLOAD_LEN must be rejected at the leb_len gate",
);
assert!(
err.contains("node payload length"),
"error must name the field 'node payload length': {err}"
);
assert!(
err.contains("exceeds limit"),
"error must say 'exceeds limit' to be actionable: {err}"
);
}
#[test]
fn wire_decode_reservation_reuses_existing_capacity() {
let mut bytes = Vec::<u8>::with_capacity(16);
let original_capacity = bytes.capacity();
reserve_decoded_vec_capacity(&mut bytes, 8, "test wire bytes")
.expect("Fix: lower target capacity should reuse existing decode storage.");
assert_eq!(bytes.capacity(), original_capacity);
}