use packr::abi::{decode, GraphBuffer, Limits, Node, NodeKind};
fn base_header() -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend_from_slice(&u32::from_le_bytes(*b"CGRF").to_le_bytes());
bytes.extend_from_slice(&1u16.to_le_bytes());
bytes.extend_from_slice(&0u16.to_le_bytes());
bytes
}
#[test]
fn rejects_bad_magic() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&u32::from_le_bytes(*b"BAD!").to_le_bytes());
bytes.extend_from_slice(&1u16.to_le_bytes());
bytes.extend_from_slice(&0u16.to_le_bytes());
bytes.extend_from_slice(&0u32.to_le_bytes());
bytes.extend_from_slice(&0u32.to_le_bytes());
assert!(decode(&bytes).is_err());
}
#[test]
fn rejects_trailing_bytes() {
let buffer = GraphBuffer {
root: 0,
nodes: vec![Node {
kind: NodeKind::Bool,
payload: vec![1],
}],
};
let mut bytes = buffer.to_bytes();
bytes.push(0xFF);
assert!(decode(&bytes).is_err());
}
#[test]
fn rejects_child_out_of_range() {
let mut bytes = base_header();
bytes.extend_from_slice(&1u32.to_le_bytes());
bytes.extend_from_slice(&0u32.to_le_bytes());
bytes.push(NodeKind::List as u8);
bytes.push(0);
bytes.extend_from_slice(&0u16.to_le_bytes());
bytes.extend_from_slice(&8u32.to_le_bytes());
bytes.extend_from_slice(&1u32.to_le_bytes());
bytes.extend_from_slice(&5u32.to_le_bytes());
assert!(decode(&bytes).is_err());
}
#[test]
fn rejects_invalid_utf8() {
let mut bytes = base_header();
bytes.extend_from_slice(&1u32.to_le_bytes());
bytes.extend_from_slice(&0u32.to_le_bytes());
bytes.push(NodeKind::String as u8);
bytes.push(0);
bytes.extend_from_slice(&0u16.to_le_bytes());
bytes.extend_from_slice(&5u32.to_le_bytes());
bytes.extend_from_slice(&2u32.to_le_bytes());
bytes.extend_from_slice(&[0xFF, 0xFF]);
assert!(decode(&bytes).is_err());
}
#[test]
fn rejects_node_count_limit() {
let mut bytes = base_header();
bytes.extend_from_slice(&5u32.to_le_bytes());
bytes.extend_from_slice(&0u32.to_le_bytes());
for _ in 0..5 {
bytes.push(NodeKind::Bool as u8);
bytes.push(0);
bytes.extend_from_slice(&0u16.to_le_bytes());
bytes.extend_from_slice(&1u32.to_le_bytes());
bytes.push(1);
}
let limits = Limits {
max_node_count: 1,
..Limits::default()
};
assert!(GraphBuffer::from_bytes_with_limits(&bytes, &limits).is_err());
}