Track lengths when copying receiver data from C++ to Rust
Co-authored-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
parent
635151bf75
commit
037bfa32f3
|
@ -70,13 +70,15 @@ static size_t GetReceiverLen(const void* ua, size_t index)
|
||||||
|
|
||||||
class CopyDataForReceiver {
|
class CopyDataForReceiver {
|
||||||
unsigned char* data;
|
unsigned char* data;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
public:
|
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 {
|
void operator()(const libzcash::SaplingPaymentAddress &zaddr) const {
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ss << zaddr;
|
ss << zaddr;
|
||||||
|
assert(length == ss.size());
|
||||||
memcpy(data, ss.data(), 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.
|
* `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(
|
std::visit(
|
||||||
CopyDataForReceiver(data),
|
CopyDataForReceiver(data, length),
|
||||||
reinterpret_cast<const libzcash::UnifiedAddress*>(ua)->GetReceiversAsParsed()[index]);
|
reinterpret_cast<const libzcash::UnifiedAddress*>(ua)->GetReceiversAsParsed()[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ typedef bool (*unknown_receiver_t)(
|
||||||
size_t len);
|
size_t len);
|
||||||
typedef uint8_t (*get_typecode_t)(const void* ua, size_t index);
|
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 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.
|
/// Parses a unified address from the given string.
|
||||||
bool zcash_address_parse_unified(
|
bool zcash_address_parse_unified(
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub type GetTypecodeCb = unsafe extern "C" fn(ua: Option<UnifiedAddressObj>, ind
|
||||||
pub type GetReceiverLenCb =
|
pub type GetReceiverLenCb =
|
||||||
unsafe extern "C" fn(ua: Option<UnifiedAddressObj>, index: usize) -> usize;
|
unsafe extern "C" fn(ua: Option<UnifiedAddressObj>, index: usize) -> usize;
|
||||||
pub type GetReceiverDataCb =
|
pub type GetReceiverDataCb =
|
||||||
unsafe extern "C" fn(ua: Option<UnifiedAddressObj>, index: usize, data: *mut u8);
|
unsafe extern "C" fn(ua: Option<UnifiedAddressObj>, index: usize, data: *mut u8, length: usize);
|
||||||
|
|
||||||
fn network_from_cstr(network: *const c_char) -> Option<Network> {
|
fn network_from_cstr(network: *const c_char) -> Option<Network> {
|
||||||
match unsafe { CStr::from_ptr(network) }.to_str().unwrap() {
|
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.
|
// TODO: Replace with Orchard support.
|
||||||
let data_len = unsafe { (receiver_len_cb.unwrap())(ua_obj, i) };
|
let data_len = unsafe { (receiver_len_cb.unwrap())(ua_obj, i) };
|
||||||
let mut data = vec![0; data_len];
|
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 {
|
unified::Receiver::Unknown {
|
||||||
typecode: 0x03,
|
typecode: 0x03,
|
||||||
data,
|
data,
|
||||||
|
@ -177,23 +177,23 @@ pub extern "C" fn zcash_address_serialize_unified(
|
||||||
}
|
}
|
||||||
unified::Typecode::Sapling => {
|
unified::Typecode::Sapling => {
|
||||||
let mut data = [0; 43];
|
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::Receiver::Sapling(data)
|
||||||
}
|
}
|
||||||
unified::Typecode::P2sh => {
|
unified::Typecode::P2sh => {
|
||||||
let mut data = [0; 20];
|
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::Receiver::P2sh(data)
|
||||||
}
|
}
|
||||||
unified::Typecode::P2pkh => {
|
unified::Typecode::P2pkh => {
|
||||||
let mut data = [0; 20];
|
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::Receiver::P2pkh(data)
|
||||||
}
|
}
|
||||||
unified::Typecode::Unknown(typecode) => {
|
unified::Typecode::Unknown(typecode) => {
|
||||||
let data_len = unsafe { (receiver_len_cb.unwrap())(ua_obj, i) };
|
let data_len = unsafe { (receiver_len_cb.unwrap())(ua_obj, i) };
|
||||||
let mut data = vec![0; data_len];
|
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 }
|
unified::Receiver::Unknown { typecode, data }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue