diff --git a/fuzz/fuzz_targets/bitcoin/deserialize_psbt.rs b/fuzz/fuzz_targets/bitcoin/deserialize_psbt.rs index cadb7820f..a651f45db 100644 --- a/fuzz/fuzz_targets/bitcoin/deserialize_psbt.rs +++ b/fuzz/fuzz_targets/bitcoin/deserialize_psbt.rs @@ -1,14 +1,37 @@ use honggfuzz::fuzz; +fn consume_random_bytes<'a>(data: &mut &'a [u8]) -> &'a [u8] { + if data.is_empty() { + return &[]; + } + + let length = (data[0] as usize) % (data.len() + 1); + let (bytes, rest) = data.split_at(length); + *data = rest; + + bytes +} + fn do_test(data: &[u8]) { - let psbt: Result = bitcoin::psbt::Psbt::deserialize(data); + let mut new_data = data; + let bytes = consume_random_bytes(&mut new_data); + let psbt: Result = bitcoin::psbt::Psbt::deserialize(bytes); match psbt { Err(_) => {} - Ok(psbt) => { + Ok(mut psbt) => { let ser = bitcoin::psbt::Psbt::serialize(&psbt); let deser = bitcoin::psbt::Psbt::deserialize(&ser).unwrap(); // Since the fuzz data could order psbt fields differently, we compare to our deser/ser instead of data assert_eq!(ser, bitcoin::psbt::Psbt::serialize(&deser)); + + let new_bytes = consume_random_bytes(&mut new_data); + let psbt_b: Result = bitcoin::psbt::Psbt::deserialize(new_bytes); + match psbt_b { + Err(_) => {}, + Ok(mut psbt_b) => { + assert_eq!(psbt_b.combine(psbt.clone()).is_ok(), psbt.combine(psbt_b).is_ok()); + } + } } } }