#![allow(missing_docs)]
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use codec_cbor::{decode_dag_cbor, CborError, MAX_DAG_CBOR_INPUT_LEN, MAX_NESTING_DEPTH};
#[test]
fn absolute_input_size_cap_rejects_before_parsing() {
let bytes = vec![0_u8; MAX_DAG_CBOR_INPUT_LEN + 1];
assert_eq!(decode_dag_cbor(&bytes), Err(CborError::InputTooLarge));
}
#[test]
fn oversized_array_length_rejected_without_allocation() {
let bytes = [0x9b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
assert_eq!(
decode_dag_cbor(&bytes),
Err(CborError::ContainerLengthExceedsInput)
);
}
#[test]
fn array_length_of_2_pow_32_rejected() {
let bytes = [0x9b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00];
assert_eq!(
decode_dag_cbor(&bytes),
Err(CborError::ContainerLengthExceedsInput)
);
}
#[test]
fn oversized_map_length_rejected_without_allocation() {
let bytes = [0xbb, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
assert_eq!(
decode_dag_cbor(&bytes),
Err(CborError::ContainerLengthExceedsInput)
);
}
#[test]
fn deeply_nested_arrays_rejected_before_stack_overflow() {
let bytes = vec![0x81u8; MAX_NESTING_DEPTH + 8];
assert_eq!(decode_dag_cbor(&bytes), Err(CborError::DepthExceeded));
}
#[test]
fn nesting_exactly_at_limit_is_accepted() {
let mut bytes = vec![0x81u8; MAX_NESTING_DEPTH];
bytes.push(0x00); let decoded = decode_dag_cbor(&bytes).expect("depth at the limit must decode");
let mut cursor = &decoded;
for _ in 0..MAX_NESTING_DEPTH {
match cursor {
codec_cbor::CborValue::Array(items) => {
assert_eq!(items.len(), 1);
cursor = &items[0];
}
other => panic!("expected array, found {other:?}"),
}
}
assert_eq!(cursor, &codec_cbor::CborValue::Int(0));
}
#[test]
fn deeply_nested_maps_rejected() {
let mut bytes = Vec::new();
for _ in 0..(MAX_NESTING_DEPTH + 4) {
bytes.push(0xa1); bytes.push(0x60); }
bytes.push(0x00); assert_eq!(decode_dag_cbor(&bytes), Err(CborError::DepthExceeded));
}
#[test]
fn truncated_array_still_rejected() {
let bytes = [0x83u8]; assert!(decode_dag_cbor(&bytes).is_err());
}
#[test]
fn nested_fill_remaining_arrays_do_not_preallocate_declared_counts() {
let mut bytes = Vec::new();
for remaining in (1_u16..=64_u16).rev() {
bytes.push(0x98); bytes.push(u8::try_from(remaining).expect("test count fits in u8"));
}
bytes.push(0x00);
assert!(decode_dag_cbor(&bytes).is_err());
}
#[test]
fn float_rejection_metadata_never_contains_payload_bits() {
for initial in [0xf9, 0xfa, 0xfb] {
for fill in [0x61, 0x00, 0xff] {
let mut bytes = vec![fill; 9];
bytes[0] = initial;
assert_eq!(
decode_dag_cbor(&bytes),
Err(CborError::DisallowedSimpleValue {
value: u64::from(initial & 0x1f)
})
);
}
}
}
#[test]
fn dag_cbor_values_support_explicit_recursive_zeroization() {
use codec_cbor::CborValue;
use zeroize::Zeroize;
let mut value = CborValue::Map(vec![(
"identity-key".to_owned(),
CborValue::Array(vec![
CborValue::String("example".to_owned()),
CborValue::Bytes(vec![0xa5; 32]),
]),
)]);
value.zeroize();
assert_eq!(value, CborValue::Map(Vec::new()));
let mut scalar = CborValue::Int(42);
scalar.zeroize();
assert_eq!(scalar, CborValue::Int(0));
}