use tls_codec::{
DeserializeBytes, Error, Size, TlsByteVecU8, TlsByteVecU16, TlsByteVecU24, TlsByteVecU32,
TlsVecU8,
};
#[test]
fn deserialize_tls_byte_vec_u8() {
let bytes = [3, 2, 1, 0];
let (result, rest) = TlsByteVecU8::tls_deserialize_bytes(&bytes).unwrap();
let expected_result = [2, 1, 0];
assert_eq!(result.as_slice(), expected_result);
assert_eq!(rest, []);
}
#[test]
fn deserialize_tls_byte_vec_u16() {
let bytes = [0, 3, 2, 1, 0];
let (result, rest) = TlsByteVecU16::tls_deserialize_bytes(&bytes).unwrap();
let expected_result = [2, 1, 0];
assert_eq!(result.as_slice(), expected_result);
assert_eq!(rest, []);
}
#[test]
fn deserialize_tls_byte_vec_u24() {
let bytes = [0, 0, 3, 2, 1, 0];
let (result, rest) = TlsByteVecU24::tls_deserialize_bytes(&bytes).unwrap();
let expected_result = [2, 1, 0];
assert_eq!(result.as_slice(), expected_result);
assert_eq!(rest, []);
}
#[test]
fn deserialize_tls_byte_vec_u32() {
let bytes = [0, 0, 0, 3, 2, 1, 0];
let (result, rest) = TlsByteVecU32::tls_deserialize_bytes(&bytes).unwrap();
let expected_result = [2, 1, 0];
assert_eq!(result.as_slice(), expected_result);
assert_eq!(rest, []);
}
#[derive(Debug, Clone, PartialEq)]
struct Zero;
impl Size for Zero {
fn tls_serialized_len(&self) -> usize {
0
}
}
impl DeserializeBytes for Zero {
fn tls_deserialize_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
Ok((Zero, bytes))
}
}
#[cfg(feature = "std")]
impl tls_codec::Deserialize for Zero {
fn tls_deserialize<R: std::io::Read>(_: &mut R) -> Result<Self, Error> {
Ok(Zero)
}
}
#[test]
fn zero_sized_element_does_not_hang_bytes() {
let input = [1u8];
let res = TlsVecU8::<Zero>::tls_deserialize_bytes(&input);
assert!(
matches!(res, Err(Error::DecodingError(_))),
"expected a decoding error, got {res:?}"
);
}
#[cfg(feature = "std")]
#[test]
fn zero_sized_element_does_not_hang_read() {
use tls_codec::Deserialize;
let input = [1u8];
let res = TlsVecU8::<Zero>::tls_deserialize(&mut input.as_slice());
assert!(
matches!(res, Err(Error::DecodingError(_))),
"expected a decoding error, got {res:?}"
);
}
#[test]
fn zero_sized_element_does_not_hang_quic_vec() {
let input = [1u8];
let res = Vec::<Zero>::tls_deserialize_bytes(&input);
assert!(
matches!(res, Err(Error::DecodingError(_))),
"expected a decoding error, got {res:?}"
);
}
#[cfg(feature = "std")]
#[test]
fn zero_sized_element_does_not_hang_quic_vec_read() {
use tls_codec::Deserialize;
let input = [1u8];
let res = Vec::<Zero>::tls_deserialize(&mut input.as_slice());
assert!(
matches!(res, Err(Error::DecodingError(_))),
"expected a decoding error, got {res:?}"
);
}
#[test]
fn overshooting_declared_length_is_rejected_bytes() {
let input = [3u8, 0x00, 0x01, 0x00, 0x02, 0xAA];
let res = TlsVecU8::<u16>::tls_deserialize_bytes(&input);
assert!(
matches!(res, Err(Error::DecodingError(_))),
"expected a decoding error, got {res:?}"
);
}
#[test]
fn overshooting_declared_length_is_rejected_quic_vec() {
let input = [3u8, 0x00, 0x01, 0x00, 0x02, 0xAA];
let res = Vec::<u16>::tls_deserialize_bytes(&input);
assert!(
matches!(res, Err(Error::DecodingError(_))),
"expected a decoding error, got {res:?}"
);
}
#[cfg(feature = "std")]
#[test]
fn overshooting_declared_length_is_rejected_read() {
use tls_codec::Deserialize;
let input = [3u8, 0x00, 0x01, 0x00, 0x02, 0xAA];
let res = TlsVecU8::<u16>::tls_deserialize(&mut input.as_slice());
assert!(
matches!(res, Err(Error::EndOfStream)),
"expected end of stream, got {res:?}"
);
}
#[cfg(feature = "std")]
#[test]
fn overshooting_declared_length_is_rejected_quic_vec_read() {
use tls_codec::Deserialize;
let input = [3u8, 0x00, 0x01, 0x00, 0x02, 0xAA];
let res = Vec::<u16>::tls_deserialize(&mut input.as_slice());
assert!(
matches!(res, Err(Error::EndOfStream)),
"expected end of stream, got {res:?}"
);
}
#[test]
fn exact_length_still_decodes() {
let input = [4u8, 0x00, 0x01, 0x00, 0x02];
let (v, rest) = TlsVecU8::<u16>::tls_deserialize_bytes(&input).expect("should decode");
assert_eq!(v.as_slice(), &[1u16, 2]);
assert!(rest.is_empty());
}
#[test]
fn truncated_byte_vec_reports_end_of_stream() {
let mut input = u32::MAX.to_be_bytes().to_vec();
input.push(0xAA); let res = TlsByteVecU32::tls_deserialize_bytes(&input);
assert!(
matches!(
res,
Err(Error::EndOfStream) | Err(Error::InvalidVectorLength)
),
"expected EndOfStream/InvalidVectorLength, got {res:?}"
);
}
#[cfg(target_pointer_width = "32")]
mod overflow_32bit {
use tls_codec::{SerializeBytes, Size};
struct HugeLen;
impl Size for HugeLen {
fn tls_serialized_len(&self) -> usize {
usize::MAX
}
}
impl SerializeBytes for HugeLen {
fn tls_serialize_bytes(&self) -> Result<Vec<u8>, tls_codec::Error> {
Ok(Vec::new())
}
}
#[test]
fn serializing_overflowing_length_is_rejected() {
let v = vec![HugeLen, HugeLen];
let res = v.tls_serialize_bytes();
assert!(
matches!(res, Err(tls_codec::Error::InvalidVectorLength)),
"expected InvalidVectorLength, got {res:?}"
);
}
#[test]
fn size_saturates_instead_of_panicking() {
let v = vec![HugeLen, HugeLen];
assert_eq!(v.tls_serialized_len(), usize::MAX);
}
}