diff --git a/src/primitives.rs b/src/primitives.rs index a6ea4bf..f388b0d 100644 --- a/src/primitives.rs +++ b/src/primitives.rs @@ -369,6 +369,18 @@ where let entries: Vec<::Entry> = Vec::deserialize(reader, version_map, app_version) .map_err(|ref err| VersionizeError::Deserialize(format!("{:?}", err)))?; + + if header.len() != entries.len() { + let msg = format!( + "Mismatch between length of FAM specified in FamStruct header ({}) \ + and actual size of FAM ({})", + header.len(), + entries.len() + ); + + return Err(VersionizeError::Deserialize(msg)); + } + // Construct the object from the array items. // Header(T) fields will be initialized by Default trait impl. let mut object = FamStructWrapper::from_entries(&entries) diff --git a/tests/test.rs b/tests/test.rs index 20b48cd..75e3cd1 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1323,6 +1323,32 @@ impl Versionize for __IncompleteArrayField { type MessageFamStructWrapper = FamStructWrapper; type Message2FamStructWrapper = FamStructWrapper; +#[test] +fn test_deserialize_famstructwrapper_invalid_len() { + let mut vm = VersionMap::new(); + vm.new_version() + .set_type_version(Message::type_id(), 2) + .new_version() + .set_type_version(Message::type_id(), 3) + .new_version() + .set_type_version(Message::type_id(), 4); + + // Create FamStructWrapper with len 2 + let state = MessageFamStructWrapper::new(0).unwrap(); + let mut buffer = [0; 256]; + + state.serialize(&mut buffer.as_mut_slice(), &vm, 2).unwrap(); + + // the `len` field of the header is the first serialized field. + // Let's corrupt it by making it bigger than the actual number of serialized elements + buffer[0] = 255; + + assert_eq!( + MessageFamStructWrapper::deserialize(&mut buffer.as_slice(), &vm, 2).unwrap_err(), + VersionizeError::Deserialize("Mismatch between length of FAM specified in FamStruct header (255) and actual size of FAM (0)".to_string()) + ); +} + #[test] fn test_versionize_famstructwrapper() { let mut vm = VersionMap::new();