#![allow(clippy::disallowed_names)] #![cfg(feature = "alloc")] extern crate alloc; mod utils; use alloc::borrow::Cow; use alloc::collections::*; #[cfg(not(feature = "serde"))] use alloc::rc::Rc; #[cfg(all(target_has_atomic = "ptr", not(feature = "serde")))] use alloc::sync::Arc; use utils::{the_same, the_same_with_comparer}; struct Foo { pub a: u32, pub b: u32, } impl bincode::Encode for Foo { fn encode( &self, encoder: &mut E, ) -> Result<(), bincode::error::EncodeError> { self.a.encode(encoder)?; self.b.encode(encoder)?; Ok(()) } } impl bincode::Decode for Foo { fn decode( decoder: &mut D, ) -> Result { Ok(Self { a: bincode::Decode::decode(decoder)?, b: bincode::Decode::decode(decoder)?, }) } } bincode::impl_borrow_decode!(Foo); #[test] fn test_vec() { let vec = bincode::encode_to_vec(Foo { a: 5, b: 10 }, bincode::config::standard()).unwrap(); assert_eq!(vec, &[5, 10]); let (foo, len): (Foo, usize) = bincode::decode_from_slice(&vec, bincode::config::standard()).unwrap(); assert_eq!(foo.a, 5); assert_eq!(foo.b, 10); assert_eq!(len, 2); let vec: Vec = bincode::decode_from_slice( &[4, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4], bincode::config::legacy(), ) .unwrap() .0; assert_eq!(vec, &[1, 2, 3, 4]); let vec: Vec> = bincode::decode_from_slice( &[4, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4], bincode::config::legacy(), ) .unwrap() .0; assert_eq!( vec, &[ Cow::Borrowed(&1), Cow::Borrowed(&2), Cow::Borrowed(&3), Cow::Borrowed(&4) ] ); } #[test] fn test_alloc_commons() { the_same::>(vec![1, 2, 3, 4, 5]); the_same(String::from("Hello world")); the_same(Box::::new(5)); the_same(Box::<[u32]>::from(vec![1, 2, 3, 4, 5])); the_same(Cow::::Owned(5)); the_same(Cow::::Borrowed(&5)); #[cfg(not(feature = "serde"))] { // Serde doesn't support Rc or Arc the_same(Rc::::new(5)); the_same(Rc::<[u32]>::from(vec![1, 2, 3, 4, 5])); #[cfg(target_has_atomic = "ptr")] { the_same(Arc::::new(5)); the_same(Arc::<[u32]>::from(vec![1, 2, 3, 4, 5])); } } the_same_with_comparer( { let mut map = BinaryHeap::::new(); map.push(1); map.push(2); map.push(3); map.push(4); map.push(5); map }, |a, b| a.iter().collect::>() == b.iter().collect::>(), ); the_same({ let mut map = BTreeMap::::new(); map.insert(5, -5); map }); the_same({ let mut set = BTreeSet::::new(); set.insert(5); set }); the_same({ let mut set = VecDeque::::new(); set.push_back(15); set.push_front(5); set }); } #[test] fn test_container_limits() { use bincode::{error::DecodeError, BorrowDecode, Decode}; const DECODE_LIMIT: usize = 100_000; // for this test we'll create a malformed package of a lot of bytes let test_cases = &[ // u64::max_value(), should overflow #[cfg(target_pointer_width = "64")] bincode::encode_to_vec(u64::max_value(), bincode::config::standard()).unwrap(), #[cfg(target_pointer_width = "32")] bincode::encode_to_vec(u32::max_value(), bincode::config::standard()).unwrap(), // A high value which doesn't overflow, but exceeds the decode limit bincode::encode_to_vec(DECODE_LIMIT as u64, bincode::config::standard()).unwrap(), ]; fn validate_fail BorrowDecode<'de> + core::fmt::Debug>(slice: &[u8]) { let result = bincode::decode_from_slice::( slice, bincode::config::standard().with_limit::(), ); let name = core::any::type_name::(); match result { Ok(_) => panic!("Decoding {} should fail, it instead succeeded", name), Err(DecodeError::OutsideUsizeRange(_)) if cfg!(target_pointer_width = "32") => {}, Err(DecodeError::LimitExceeded) => {}, Err(e) => panic!("Expected OutsideUsizeRange (on 32 bit platforms) or LimitExceeded whilst decoding {}, got {:?}", name, e), } } for slice in test_cases { validate_fail::>(slice); validate_fail::>(slice); validate_fail::>(slice); validate_fail::>(slice); validate_fail::>(slice); validate_fail::(slice); #[cfg(feature = "std")] { validate_fail::>(slice); validate_fail::>(slice); } } } #[cfg(target_has_atomic = "ptr")] #[test] fn test_arc_str() { use alloc::sync::Arc; let start: Arc = Arc::from("Example String"); let mut target = [0u8; 100]; let config = bincode::config::standard(); let len = { let start: Arc = Arc::clone(&start); bincode::encode_into_slice(start, &mut target, config).unwrap() }; let slice = &target[..len]; let decoded: Arc = bincode::borrow_decode_from_slice(slice, config).unwrap().0; assert_eq!(decoded, start); }