diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs index 5adc81654..7bf5791f0 100644 --- a/bitcoin/src/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -255,8 +255,9 @@ impl Psbt { == derivation2[derivation2.len() - derivation1.len()..]) { continue; - } else if derivation2[..] - == derivation1[derivation1.len() - derivation2.len()..] + } else if derivation2.len() <= derivation1.len() + && derivation2[..] + == derivation1[derivation1.len() - derivation2.len()..] { entry.insert((fingerprint1, derivation1)); continue; @@ -2116,6 +2117,16 @@ mod tests { assert_eq!(psbt1, psbt2); } + + // https://github.com/rust-bitcoin/rust-bitcoin/issues/3628 + #[test] + fn test_combine_psbt_fuzz_3628() { + let mut psbt1 = hex_psbt(include_str!("../../tests/data/psbt_fuzz1.hex")).unwrap(); + let psbt2 = hex_psbt(include_str!("../../tests/data/psbt_fuzz2.hex")).unwrap(); + + assert!(matches!(psbt1.combine(psbt2).unwrap_err(), Error::CombineInconsistentKeySources(_))); + } + #[cfg(feature = "rand-std")] fn gen_keys() -> (PrivateKey, PublicKey, Secp256k1) { use secp256k1::rand::thread_rng; diff --git a/bitcoin/tests/data/psbt_fuzz1.hex b/bitcoin/tests/data/psbt_fuzz1.hex new file mode 100644 index 000000000..dd3c9b7ed --- /dev/null +++ b/bitcoin/tests/data/psbt_fuzz1.hex @@ -0,0 +1 @@ +70736274ff01000a000000ff0000000074ff4f010488b21eff02000001004a92244992244902030203030303030303030303030303030303030303030303030303030303030303f4000000000000000a000208ffffffff08080804000000000000000c080808000b0000000000010000 \ No newline at end of file diff --git a/bitcoin/tests/data/psbt_fuzz2.hex b/bitcoin/tests/data/psbt_fuzz2.hex new file mode 100644 index 000000000..8a33cf01c --- /dev/null +++ b/bitcoin/tests/data/psbt_fuzz2.hex @@ -0,0 +1 @@ +70736274ff01000a000000ff0000000074ff4f010488b21eff02000001004a92244992244902030203030303030303030303030303030303030303030303030303030303030303f4000000000000000a000208ffffffff080808040000000000000008000000000000001000 \ No newline at end of file