diff --git a/spdmlib/src/message/mod.rs b/spdmlib/src/message/mod.rs index 38bbef8..fc7059e 100644 --- a/spdmlib/src/message/mod.rs +++ b/spdmlib/src/message/mod.rs @@ -606,6 +606,12 @@ mod tests { #[test] fn test_case0_spdm_message() { + let mut versions = gen_array_clone(SpdmVersionStruct::default(), MAX_SPDM_VERSION_COUNT); + versions[0].update = 100; + versions[0].version = SpdmVersion::SpdmVersion10; + versions[1].update = 100; + versions[1].version = SpdmVersion::SpdmVersion11; + let value = SpdmMessage { header: SpdmMessageHeader { version: SpdmVersion::SpdmVersion10, @@ -613,13 +619,7 @@ mod tests { }, payload: SpdmMessagePayload::SpdmVersionResponse(SpdmVersionResponsePayload { version_number_entry_count: 0x02, - versions: gen_array_clone( - SpdmVersionStruct { - update: 100, - version: SpdmVersion::SpdmVersion11, - }, - MAX_SPDM_VERSION_COUNT, - ), + versions, }), }; @@ -633,10 +633,10 @@ mod tests { ); if let SpdmMessagePayload::SpdmVersionResponse(payload) = &spdm_message.payload { assert_eq!(payload.version_number_entry_count, 0x02); - for i in 0..2 { - assert_eq!(payload.versions[i].update, 100); - assert_eq!(payload.versions[i].version, SpdmVersion::SpdmVersion11); - } + assert_eq!(payload.versions[0].update, 100); + assert_eq!(payload.versions[0].version, SpdmVersion::SpdmVersion10); + assert_eq!(payload.versions[1].update, 100); + assert_eq!(payload.versions[1].version, SpdmVersion::SpdmVersion11); } } #[test] diff --git a/spdmlib/src/message/version.rs b/spdmlib/src/message/version.rs index 2c2c4ef..23cadaf 100644 --- a/spdmlib/src/message/version.rs +++ b/spdmlib/src/message/version.rs @@ -106,18 +106,20 @@ impl SpdmCodec for SpdmVersionResponsePayload { }, MAX_SPDM_VERSION_COUNT, ); + let mut version_exist_map: [u8; MAX_SPDM_VERSION_COUNT] = [0; MAX_SPDM_VERSION_COUNT]; let mut version_count = 0; let rest = r.take(version_number_entry_count as usize * 2)?; for i in 0..version_number_entry_count { if let Some(ver) = SpdmVersionStruct::read_bytes(&rest[i as usize * 2..]) { - if version_count < MAX_SPDM_VERSION_COUNT { + let index = ver.version as usize; + if version_exist_map[index] == 0 { + version_exist_map[index] = 1; versions[version_count] = ver; version_count += 1; } else { - // the buffer is full now, stop for scaning more versions - break; + // for duplicated version, ignore it } } else { // for unknown versions, @@ -180,15 +182,15 @@ mod tests { fn test_case0_spdm_version_response_payload() { let u8_slice = &mut [0u8; 8]; let mut writer = Writer::init(u8_slice); + let mut versions = gen_array_clone(SpdmVersionStruct::default(), MAX_SPDM_VERSION_COUNT); + versions[0].update = 100; + versions[0].version = SpdmVersion::SpdmVersion10; + versions[1].update = 100; + versions[1].version = SpdmVersion::SpdmVersion11; + let value = SpdmVersionResponsePayload { version_number_entry_count: 2u8, - versions: gen_array_clone( - SpdmVersionStruct { - update: 100u8, - version: SpdmVersion::SpdmVersion10, - }, - MAX_SPDM_VERSION_COUNT, - ), + versions, }; create_spdm_context!(context); @@ -200,13 +202,16 @@ mod tests { SpdmVersionResponsePayload::spdm_read(&mut context, &mut reader).unwrap(); assert_eq!(version_response.version_number_entry_count, 2u8); - for i in 0..2 { - assert_eq!(version_response.versions[i].update, 100u8); - assert_eq!( - version_response.versions[i].version, - SpdmVersion::SpdmVersion10 - ); - } + assert_eq!(version_response.versions[0].update, 100); + assert_eq!( + version_response.versions[0].version, + SpdmVersion::SpdmVersion10 + ); + assert_eq!(version_response.versions[1].update, 100); + assert_eq!( + version_response.versions[1].version, + SpdmVersion::SpdmVersion11 + ); assert_eq!(0, reader.left()); } #[test] diff --git a/spdmlib/src/message/version_test.rs b/spdmlib/src/message/version_test.rs index ecea226..30e6ecb 100644 --- a/spdmlib/src/message/version_test.rs +++ b/spdmlib/src/message/version_test.rs @@ -9,7 +9,7 @@ extern crate alloc; #[test] fn test_case1_spdmversion_struct() { - // Validata VERSION response VersionNumberEntryCount beyond maximum allowed size. + // Validate VERSION response VersionNumberEntryCount beyond maximum allowed size. let u8_slice = &mut [0u8; 100]; // VersionNumberEntryCount = 0xfe @@ -19,7 +19,7 @@ fn test_case1_spdmversion_struct() { let res = SpdmVersionResponsePayload::spdm_read(&mut context, &mut reader); assert!(res.is_none()); - // Validata VERSION response VersionNumberEntryCount 0 size. + // Validate VERSION response VersionNumberEntryCount 0 size. let u8_slice = &mut [0u8; 100]; // VersionNumberEntryCount = 0x0 @@ -27,5 +27,19 @@ fn test_case1_spdmversion_struct() { let mut reader = Reader::init(u8_slice); create_spdm_context!(context); let res = SpdmVersionResponsePayload::spdm_read(&mut context, &mut reader); - assert!(res.is_none()) + assert!(res.is_none()); + + // Validate VERSION response VersionNumberEntryCount beyond MAX_SPDM_VERSION_COUNT and with duplicated version entries. + let u8_slice: &mut [u8; 16] = &mut [ + 0x0, 0x0, 0x0, 0x6, 0x0, 0x10, 0x0, 0x10, 0x0, 0x11, 0x0, 0x12, 0x0, 0x13, 0x0, 0x13, + ]; + let mut reader = Reader::init(u8_slice); + create_spdm_context!(context); + let res = SpdmVersionResponsePayload::spdm_read(&mut context, &mut reader); + let version = res.unwrap(); + assert_eq!(version.version_number_entry_count, 4); + assert_eq!(version.versions[0].version, SpdmVersion::SpdmVersion10); + assert_eq!(version.versions[1].version, SpdmVersion::SpdmVersion11); + assert_eq!(version.versions[2].version, SpdmVersion::SpdmVersion12); + assert_eq!(version.versions[3].version, SpdmVersion::SpdmVersion13); }