#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use jcs_admit::{admit, admit_with, Error, Options, DEFAULT_MAX_DEPTH};
fn nest(depth: usize) -> Vec<u8> {
let mut v = vec![b'['; depth];
v.resize(depth * 2, b']');
v
}
#[test]
fn twice_the_cap_is_refused_and_the_cap_itself_is_not() {
let too_deep = nest(DEFAULT_MAX_DEPTH * 2);
assert!(
matches!(admit(&too_deep), Err(Error::TooDeep { .. })),
"a document nested to twice the cap must be refused with Error::TooDeep, got {:?}",
admit(&too_deep).map(|b| b.len())
);
let at_bound = nest(DEFAULT_MAX_DEPTH);
assert!(
admit(&at_bound).is_ok(),
"the cap itself must still canonicalize"
);
}
#[test]
fn the_boundary_is_exact() {
assert!(
admit(&nest(DEFAULT_MAX_DEPTH)).is_ok(),
"{DEFAULT_MAX_DEPTH} must pass"
);
assert!(
matches!(
admit(&nest(DEFAULT_MAX_DEPTH + 1)),
Err(Error::TooDeep { limit: 128, .. })
),
"{} must be refused",
DEFAULT_MAX_DEPTH + 1
);
}
#[test]
fn an_empty_innermost_container_is_charged() {
let mut v = vec![b'['; DEFAULT_MAX_DEPTH];
v.extend_from_slice(b"{}");
v.resize(v.len() + DEFAULT_MAX_DEPTH, b']');
assert!(
matches!(admit(&v), Err(Error::TooDeep { .. })),
"an empty object at level {} must be refused",
DEFAULT_MAX_DEPTH + 1
);
}
#[test]
fn objects_are_charged_like_arrays() {
let mut deep = Vec::new();
for _ in 0..DEFAULT_MAX_DEPTH + 1 {
deep.extend_from_slice(br#"{"a":"#);
}
deep.extend_from_slice(b"1");
deep.resize(deep.len() + DEFAULT_MAX_DEPTH + 1, b'}');
assert!(matches!(admit(&deep), Err(Error::TooDeep { .. })));
}
#[test]
fn the_cap_is_configurable_in_both_directions() {
let opts = Options::rfc8785().max_depth(4);
assert!(admit_with(&nest(4), &opts).is_ok());
assert!(matches!(
admit_with(&nest(5), &opts),
Err(Error::TooDeep { limit: 4, .. })
));
}
#[test]
fn oversized_input_is_refused_before_parsing() {
let mut big = vec![b' '; jcs_admit::DEFAULT_MAX_BYTES + 1];
big[0] = b'[';
let last = big.len() - 1;
big[last] = b']';
assert!(matches!(admit(&big), Err(Error::TooLarge { .. })));
}
const HARD_CEILING: usize = 512;
#[test]
fn the_cap_cannot_be_raised_into_a_stack_overflow() {
let opts = Options::rfc8785().max_depth(usize::MAX).max_bytes(None);
match admit_with(&nest(HARD_CEILING + 1), &opts) {
Err(Error::TooDeep { limit, .. }) => assert_eq!(
limit, HARD_CEILING,
"a raised cap must be reported at the ceiling actually enforced"
),
other => panic!(
"a cap raised past the ceiling must still refuse, got {:?}",
other.map(|bytes| bytes.len())
),
}
assert!(
admit_with(&nest(HARD_CEILING), &opts).is_ok(),
"the ceiling itself must not be refused, or the guard passes by being over-tight"
);
}
#[test]
fn a_raise_below_the_ceiling_is_honoured_exactly() {
let opts = Options::rfc8785().max_depth(200);
assert!(admit_with(&nest(200), &opts).is_ok());
assert!(matches!(
admit_with(&nest(201), &opts),
Err(Error::TooDeep { limit: 200, .. })
));
}