// SPDX-License-Identifier: AGPL-3.0-only use super::*; use shared::protocol::{ ClientHello, ControlMessage, FeatureFlags, PROTOCOL_VERSION, PlayerIdentity, }; /// Round-trips a set of boundary values through the varint codec, asserting both the decoded value and the exact byte length consumed. #[test] fn varint_round_trip_boundaries() -> Result<(), NetError> { let cases = [ 0, 1, 127, 128, 16_383, 16_384, u64::from(u32::MAX), u64::MAX, ]; for value in cases { let mut buf = Vec::new(); write_varint(value, &mut buf); let (decoded, consumed) = read_varint(&buf)?; assert_eq!(decoded, value, "decoded value mismatch"); assert_eq!( consumed, buf.len(), "consumed length must equal encoded length" ); } Ok(()) } /// A frame encodes as `[varint payload length][payload]`, and decoding the prefix recovers exactly the payload byte count. #[test] fn encode_frame_prefixes_payload_length() -> Result<(), NetError> { let msg = ControlMessage::ClientHello(ClientHello { protocol_version: PROTOCOL_VERSION, client_build: "synvael-client-0.1.0".to_string(), player_identity: PlayerIdentity { display_name: "Player1".to_string(), }, installed_packs: Vec::new(), requested_features: FeatureFlags(0), }); let payload = postcard::to_stdvec(&msg)?; let frame = encode_frame(&msg)?; let (declared_len, prefix_bytes) = read_varint(&frame)?; assert_eq!( declared_len, payload.len() as u64, "prefix must equal payload length" ); assert_eq!( &frame[prefix_bytes..], payload.as_slice(), "payload bytes must follow the prefix unchanged" ); Ok(()) } /// Confirms the documented one/two-byte boundary encodings so a regression in the continuation logic is caught directly. #[test] fn varint_boundary_lengths() { let mut buf = Vec::new(); write_varint(127, &mut buf); assert_eq!(buf.len(), 1, "127 must encode in a single byte"); buf.clear(); write_varint(128, &mut buf); assert_eq!(buf.len(), 2, "128 must encode in two bytes"); } /// A varint whose final byte still sets the continuation bit is a truncated buffer and must error rather than panic. #[test] fn varint_truncated_is_error() { // Two bytes both flagged as "continued", with no terminating byte. let truncated = [0x80u8, 0x80u8]; assert!( read_varint(&truncated).is_err(), "truncated varint must return an error" ); } /// An encoding longer than the ten bytes a `u64` can occupy is rejected as overlong rather than silently accepted. #[test] fn varint_overlong_is_error() { // Eleven continuation bytes followed by a terminator exceeds the u64 limit. let overlong = [0x80u8; 11]; assert!( read_varint(&overlong).is_err(), "overlong varint must return an error" ); } /// A declared length within the cap is accepted; one exceeding it is rejected as `FrameTooLarge` before any allocation. #[test] fn frame_len_bound_is_enforced() { assert_eq!( check_frame_len(64, 128).ok(), Some(64), "a length within the cap is accepted" ); assert_eq!( check_frame_len(128, 128).ok(), Some(128), "a length equal to the cap is accepted" ); assert!( matches!( check_frame_len(129, 128), Err(NetError::FrameTooLarge { len: 129, max: 128 }) ), "a length over the cap must be rejected", ); }