diff --git a/src/key_io.cpp b/src/key_io.cpp index 44f56e44a..86bec602e 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -70,13 +70,15 @@ static size_t GetReceiverLen(const void* ua, size_t index) class CopyDataForReceiver { unsigned char* data; + size_t length; public: - CopyDataForReceiver(unsigned char* data) : data(data) {} + CopyDataForReceiver(unsigned char* data, size_t length) : data(data), length(length) {} void operator()(const libzcash::SaplingPaymentAddress &zaddr) const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << zaddr; + assert(length == ss.size()); memcpy(data, ss.data(), ss.size()); } @@ -96,10 +98,10 @@ public: /** * `data` MUST be the correct length for the receiver at this index. */ -static void GetReceiver(const void* ua, size_t index, unsigned char* data) +static void GetReceiver(const void* ua, size_t index, unsigned char* data, size_t length) { std::visit( - CopyDataForReceiver(data), + CopyDataForReceiver(data, length), reinterpret_cast(ua)->GetReceiversAsParsed()[index]); } diff --git a/src/rust/include/rust/address.h b/src/rust/include/rust/address.h index ab2f94a30..ab9e8750a 100644 --- a/src/rust/include/rust/address.h +++ b/src/rust/include/rust/address.h @@ -17,7 +17,7 @@ typedef bool (*unknown_receiver_t)( size_t len); typedef uint8_t (*get_typecode_t)(const void* ua, size_t index); typedef size_t (*get_receiver_len_t)(const void* ua, size_t index); -typedef void (*get_receiver_t)(const void* ua, size_t index, unsigned char* data); +typedef void (*get_receiver_t)(const void* ua, size_t index, unsigned char* data, size_t length); /// Parses a unified address from the given string. bool zcash_address_parse_unified( diff --git a/src/rust/src/address_ffi.rs b/src/rust/src/address_ffi.rs index c1ab48b77..e0bc66ba0 100644 --- a/src/rust/src/address_ffi.rs +++ b/src/rust/src/address_ffi.rs @@ -21,7 +21,7 @@ pub type GetTypecodeCb = unsafe extern "C" fn(ua: Option, ind pub type GetReceiverLenCb = unsafe extern "C" fn(ua: Option, index: usize) -> usize; pub type GetReceiverDataCb = - unsafe extern "C" fn(ua: Option, index: usize, data: *mut u8); + unsafe extern "C" fn(ua: Option, index: usize, data: *mut u8, length: usize); fn network_from_cstr(network: *const c_char) -> Option { match unsafe { CStr::from_ptr(network) }.to_str().unwrap() { @@ -169,7 +169,7 @@ pub extern "C" fn zcash_address_serialize_unified( // TODO: Replace with Orchard support. let data_len = unsafe { (receiver_len_cb.unwrap())(ua_obj, i) }; let mut data = vec![0; data_len]; - unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr()) }; + unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr(), data_len) }; unified::Receiver::Unknown { typecode: 0x03, data, @@ -177,23 +177,23 @@ pub extern "C" fn zcash_address_serialize_unified( } unified::Typecode::Sapling => { let mut data = [0; 43]; - unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr()) }; + unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr(), data.len()) }; unified::Receiver::Sapling(data) } unified::Typecode::P2sh => { let mut data = [0; 20]; - unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr()) }; + unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr(), data.len()) }; unified::Receiver::P2sh(data) } unified::Typecode::P2pkh => { let mut data = [0; 20]; - unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr()) }; + unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr(), data.len()) }; unified::Receiver::P2pkh(data) } unified::Typecode::Unknown(typecode) => { let data_len = unsafe { (receiver_len_cb.unwrap())(ua_obj, i) }; let mut data = vec![0; data_len]; - unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr()) }; + unsafe { (receiver_cb.unwrap())(ua_obj, i, data.as_mut_ptr(), data_len) }; unified::Receiver::Unknown { typecode, data } } },