From aade06d9a96a2cfa5a0596dd40ca5faeff5e07ce Mon Sep 17 00:00:00 2001 From: gered Date: Thu, 20 May 2021 19:32:09 -0400 Subject: [PATCH] re-organize some unit tests --- psoutils/src/quest/bin.rs | 81 ++++++++++++++++++++++++++++++++++++--- psoutils/src/quest/dat.rs | 27 ++++++------- 2 files changed, 89 insertions(+), 19 deletions(-) diff --git a/psoutils/src/quest/bin.rs b/psoutils/src/quest/bin.rs index 96df1e3..15319a1 100644 --- a/psoutils/src/quest/bin.rs +++ b/psoutils/src/quest/bin.rs @@ -447,7 +447,7 @@ pub mod tests { } #[test] - pub fn bad_input_data_results_in_errors() -> Result<(), QuestBinError> { + pub fn error_on_load_from_zero_bytes() { let mut data: &[u8] = &[]; assert_matches!( QuestBin::from_uncompressed_bytes(&mut data), @@ -457,7 +457,10 @@ pub mod tests { QuestBin::from_compressed_bytes(&mut data), Err(QuestBinError::PrsCompressionError(..)) ); + } + #[test] + pub fn error_on_load_from_garbage_bytes() { let mut data: &[u8] = b"This is definitely not a quest"; assert_matches!( QuestBin::from_uncompressed_bytes(&mut data), @@ -467,16 +470,24 @@ pub mod tests { QuestBin::from_compressed_bytes(&mut data), Err(QuestBinError::PrsCompressionError(..)) ); + } - // bad data, but with valid object_code_offset to start ... + #[test] + pub fn error_on_mostly_junk_header() { + // the only correct part of this header is the object_code_offset let mut data = Vec::::new(); - data.write_u32::(QUEST_BIN_HEADER_SIZE as u32)?; - data.write_all(b"This is also definitely not a quest")?; + data.write_u32::(QUEST_BIN_HEADER_SIZE as u32) + .unwrap(); + data.write_all(b"This is also definitely not a quest") + .unwrap(); assert_matches!( QuestBin::from_uncompressed_bytes(&mut data.as_slice()), Err(QuestBinError::DataFormatError(..)) ); + } + #[test] + pub fn error_on_header_with_bad_language_value() { // otherwise valid looking bin_header, but bad language value let mut data: &[u8] = &[ 0xD4, 0x01, 0x00, 0x00, // object_code_offset @@ -491,7 +502,10 @@ pub mod tests { QuestBin::from_uncompressed_bytes(&mut data), Err(QuestBinError::DataFormatError(..)) ); + } + #[test] + pub fn error_on_header_with_garbage_text_fields() { // valid bin_header (so far) ... let header: &[u8] = &[ 0xD4, 0x01, 0x00, 0x00, // object_code_offset @@ -502,7 +516,9 @@ pub mod tests { 0x00, // language 0x3A, 0x00, // quest_number_and_episode ]; - // ... and lets append random garbage to it + // ... and lets append random garbage to it. + // this garbage will read as text fields (name, etc) and be decoded from shift jis which + // will fail ... let mut random_garbage = [0u8; 4096]; let mut rng = StdRng::seed_from_u64(123456); random_garbage.try_fill(&mut rng).unwrap(); @@ -511,7 +527,10 @@ pub mod tests { QuestBin::from_uncompressed_bytes(&mut data.as_slice()), Err(QuestBinError::DataFormatError(..)) ); + } + #[test] + pub fn error_on_bin_that_is_too_small() { // a complete valid bin_header ... let header: &[u8] = &[ 0xD4, 0x01, 0x00, 0x00, 0xA4, 0x09, 0x00, 0x00, 0x4C, 0x19, 0x00, 0x00, 0xFF, 0xFF, @@ -562,7 +581,57 @@ pub mod tests { QuestBin::from_uncompressed_bytes(&mut data.as_slice()), Err(QuestBinError::IoError(..)) ); + } - Ok(()) + #[test] + pub fn error_on_non_dword_sized_function_offset_table() { + // i don't think this scenario being tested is really important ... it would mean something + // is generating garbage function_offset_tables to begin with ... + + // a complete valid bin_header ... + let header: &[u8] = &[ + 0xD4, 0x01, 0x00, 0x00, 0xA4, 0x09, 0x00, 0x00, 0x4A, 0x19, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x3A, 0x00, 0x4C, 0x6F, 0x73, 0x74, 0x20, 0x48, 0x45, 0x41, + 0x54, 0x20, 0x53, 0x57, 0x4F, 0x52, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x65, 0x74, 0x72, + 0x69, 0x65, 0x76, 0x65, 0x20, 0x61, 0x0A, 0x77, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x20, + 0x66, 0x72, 0x6F, 0x6D, 0x0A, 0x61, 0x20, 0x44, 0x72, 0x61, 0x67, 0x6F, 0x6E, 0x21, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6C, + 0x69, 0x65, 0x6E, 0x74, 0x3A, 0x20, 0x20, 0x48, 0x6F, 0x70, 0x6B, 0x69, 0x6E, 0x73, + 0x2C, 0x20, 0x68, 0x75, 0x6E, 0x74, 0x65, 0x72, 0x0A, 0x51, 0x75, 0x65, 0x73, 0x74, + 0x3A, 0x0A, 0x20, 0x4D, 0x79, 0x20, 0x77, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x20, 0x77, + 0x61, 0x73, 0x20, 0x74, 0x61, 0x6B, 0x65, 0x6E, 0x0A, 0x20, 0x66, 0x72, 0x6F, 0x6D, + 0x20, 0x6D, 0x65, 0x20, 0x77, 0x68, 0x65, 0x6E, 0x20, 0x49, 0x20, 0x77, 0x61, 0x73, + 0x0A, 0x20, 0x66, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x20, 0x44, + 0x72, 0x61, 0x67, 0x6F, 0x6E, 0x2E, 0x0A, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x3A, + 0x20, 0x20, 0x3F, 0x3F, 0x3F, 0x20, 0x4D, 0x65, 0x73, 0x65, 0x74, 0x61, 0x0A, 0x0A, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + let object_code_data = [0u8; 2000]; + let function_offset_table_data = [0u8; 4006]; // size here matches header above, but it is still a bad size + let data = [header, &object_code_data, &function_offset_table_data].concat(); + + assert_matches!( + QuestBin::from_uncompressed_bytes(&mut data.as_slice()), + Err(QuestBinError::DataFormatError(..)) + ); } } diff --git a/psoutils/src/quest/dat.rs b/psoutils/src/quest/dat.rs index c23bf27..16ec2c6 100644 --- a/psoutils/src/quest/dat.rs +++ b/psoutils/src/quest/dat.rs @@ -632,7 +632,7 @@ pub mod tests { } #[test] - pub fn bad_input_data_results_in_errors() -> Result<(), QuestDatError> { + pub fn error_on_load_from_zero_bytes() { let mut data: &[u8] = &[]; assert_matches!( QuestDat::from_uncompressed_bytes(&mut data), @@ -642,7 +642,10 @@ pub mod tests { QuestDat::from_compressed_bytes(&mut data), Err(QuestDatError::PrsCompressionError(..)) ); + } + #[test] + pub fn error_on_load_from_garbage_bytes() { let mut data: &[u8] = b"This is definitely not a quest"; assert_matches!( QuestDat::from_uncompressed_bytes(&mut data), @@ -652,8 +655,11 @@ pub mod tests { QuestDat::from_compressed_bytes(&mut data), Err(QuestDatError::PrsCompressionError(..)) ); + } - // dat table header with a table_size issue + #[test] + pub fn errpr_on_table_header_with_bad_table_size() { + // dat table header with a table_size issue (table_size != table_body_size + 16) let mut header: &[u8] = &[ 0x01, 0x00, 0x00, 0x00, // table_type 0xD3, 0x08, 0x00, 0x00, // table_size @@ -664,7 +670,10 @@ pub mod tests { QuestDat::from_uncompressed_bytes(&mut header), Err(QuestDatError::DataFormatError(..)) ); + } + #[test] + pub fn error_on_table_header_with_bad_table_type() { // dat table header with a table_type issue let mut header: &[u8] = &[ 0x11, 0x00, 0x00, 0x00, // table_type @@ -676,7 +685,10 @@ pub mod tests { QuestDat::from_uncompressed_bytes(&mut header), Err(QuestDatError::DataFormatError(..)) ); + } + #[test] + pub fn error_on_table_with_body_data_that_is_too_small() { // a valid dat table header ... let header: &[u8] = &[ 0x01, 0x00, 0x00, 0x00, // table_type @@ -693,16 +705,5 @@ pub mod tests { QuestDat::from_uncompressed_bytes(&mut data.as_slice()), Err(QuestDatError::IoError(..)) ); - - // totally random data which should be interpreted as an invalid table header - let mut data = vec![0u8; 1024]; - let mut rng = StdRng::seed_from_u64(15785357); - data.try_fill(&mut rng).unwrap(); - assert_matches!( - QuestDat::from_uncompressed_bytes(&mut data.as_slice()), - Err(QuestDatError::DataFormatError(..)) - ); - - Ok(()) } }