Skip to content

Commit 777b84f

Browse files
committed
fix(ffi): Free FFIManagedWalletInfo in tests to prevent memory leaks
Tests now properly heap-allocate FFIManagedWalletInfo using Box and call managed_wallet_free for cleanup, matching how C code would use the FFI.
1 parent 43a696a commit 777b84f

2 files changed

Lines changed: 32 additions & 32 deletions

File tree

key-wallet-ffi/src/managed_wallet.rs

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ impl FFIManagedWalletInfo {
3636
pub fn inner_mut(&mut self) -> &mut ManagedWalletInfo {
3737
unsafe { &mut *(self.inner as *mut ManagedWalletInfo) }
3838
}
39+
3940
}
4041

4142
/// Get the next unused receive address
@@ -748,14 +749,14 @@ mod tests {
748749
assert!(!wallet.is_null());
749750
assert_eq!(error.code, FFIErrorCode::Success);
750751

751-
// Create managed wallet info from the wallet
752+
// Create managed wallet info from the wallet (heap-allocated like C would do)
752753
let wallet_rust = unsafe { &(*wallet).wallet };
753754
let managed_info = ManagedWalletInfo::from_wallet(wallet_rust);
754-
let mut ffi_managed = FFIManagedWalletInfo::new(managed_info);
755+
let ffi_managed = Box::into_raw(Box::new(FFIManagedWalletInfo::new(managed_info)));
755756

756757
// Test get_next_receive_address with valid pointers
757758
let receive_addr = unsafe {
758-
managed_wallet_get_next_bip44_receive_address(&mut ffi_managed, wallet, 0, &mut error)
759+
managed_wallet_get_next_bip44_receive_address(ffi_managed, wallet, 0, &mut error)
759760
};
760761

761762
if !receive_addr.is_null() {
@@ -776,7 +777,7 @@ mod tests {
776777

777778
// Test get_next_change_address with valid pointers
778779
let change_addr = unsafe {
779-
managed_wallet_get_next_bip44_change_address(&mut ffi_managed, wallet, 0, &mut error)
780+
managed_wallet_get_next_bip44_change_address(ffi_managed, wallet, 0, &mut error)
780781
};
781782

782783
if !change_addr.is_null() {
@@ -795,6 +796,7 @@ mod tests {
795796

796797
// Clean up
797798
unsafe {
799+
managed_wallet_free(ffi_managed);
798800
wallet::wallet_free(wallet);
799801
}
800802
}
@@ -869,20 +871,15 @@ mod tests {
869871
// Insert the managed account directly into managed_info's accounts
870872
managed_info.accounts.insert(managed_account);
871873

872-
// Create wrapper for managed info
873-
let mut ffi_managed = FFIManagedWalletInfo::new(managed_info);
874+
// Create wrapper for managed info (heap-allocated like C would do)
875+
let ffi_managed = Box::into_raw(Box::new(FFIManagedWalletInfo::new(managed_info)));
874876

875877
// Use the existing wallet pointer
876878
let ffi_wallet_ptr = wallet_ptr;
877879

878880
// Test 1: Get next receive address
879881
let receive_addr = unsafe {
880-
managed_wallet_get_next_bip44_receive_address(
881-
&mut ffi_managed,
882-
ffi_wallet_ptr,
883-
0,
884-
&mut error,
885-
)
882+
managed_wallet_get_next_bip44_receive_address(ffi_managed, ffi_wallet_ptr, 0, &mut error)
886883
};
887884

888885
assert!(!receive_addr.is_null());
@@ -895,12 +892,7 @@ mod tests {
895892

896893
// Test 2: Get next change address
897894
let change_addr = unsafe {
898-
managed_wallet_get_next_bip44_change_address(
899-
&mut ffi_managed,
900-
ffi_wallet_ptr,
901-
0,
902-
&mut error,
903-
)
895+
managed_wallet_get_next_bip44_change_address(ffi_managed, ffi_wallet_ptr, 0, &mut error)
904896
};
905897

906898
assert!(!change_addr.is_null());
@@ -917,7 +909,7 @@ mod tests {
917909

918910
let success = unsafe {
919911
managed_wallet_get_bip_44_external_address_range(
920-
&mut ffi_managed,
912+
ffi_managed,
921913
ffi_wallet_ptr,
922914
0,
923915
0,
@@ -950,7 +942,7 @@ mod tests {
950942

951943
let success = unsafe {
952944
managed_wallet_get_bip_44_internal_address_range(
953-
&mut ffi_managed,
945+
ffi_managed,
954946
ffi_wallet_ptr,
955947
0,
956948
0,
@@ -980,6 +972,7 @@ mod tests {
980972

981973
// Clean up
982974
unsafe {
975+
managed_wallet_free(ffi_managed);
983976
wallet::wallet_free(wallet_ptr);
984977
}
985978
}

key-wallet-ffi/src/utxo_tests.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,20 @@ mod utxo_tests {
113113
let mut utxos_out: *mut FFIUTXO = ptr::null_mut();
114114
let mut count_out: usize = 0;
115115

116-
// Create an empty managed wallet info
116+
// Create an empty managed wallet info (heap-allocated like C would do)
117117
let managed_info = ManagedWalletInfo::new(Network::Testnet, [0u8; 32]);
118-
let ffi_managed_info = FFIManagedWalletInfo::new(managed_info);
118+
let ffi_managed_info = Box::into_raw(Box::new(FFIManagedWalletInfo::new(managed_info)));
119119

120120
let result = unsafe {
121-
managed_wallet_get_utxos(&ffi_managed_info, &mut utxos_out, &mut count_out, error)
121+
managed_wallet_get_utxos(&*ffi_managed_info, &mut utxos_out, &mut count_out, error)
122122
};
123123

124124
assert!(result);
125125
assert_eq!(unsafe { (*error).code }, FFIErrorCode::Success);
126126
assert_eq!(count_out, 0);
127127
assert!(utxos_out.is_null());
128+
129+
unsafe { crate::managed_wallet::managed_wallet_free(ffi_managed_info) };
128130
}
129131

130132
// Note: There's no individual utxo_free function, only utxo_array_free
@@ -229,10 +231,10 @@ mod utxo_tests {
229231

230232
managed_info.accounts.insert(bip44_account);
231233

232-
let ffi_managed_info = FFIManagedWalletInfo::new(managed_info);
234+
let ffi_managed_info = Box::into_raw(Box::new(FFIManagedWalletInfo::new(managed_info)));
233235

234236
let result = unsafe {
235-
managed_wallet_get_utxos(&ffi_managed_info, &mut utxos_out, &mut count_out, error)
237+
managed_wallet_get_utxos(&*ffi_managed_info, &mut utxos_out, &mut count_out, error)
236238
};
237239

238240
assert!(result);
@@ -267,6 +269,7 @@ mod utxo_tests {
267269
// Clean up
268270
unsafe {
269271
utxo_array_free(utxos_out, count_out);
272+
crate::managed_wallet::managed_wallet_free(ffi_managed_info);
270273
}
271274
}
272275

@@ -393,10 +396,10 @@ mod utxo_tests {
393396
}
394397
managed_info.accounts.insert(coinjoin_account);
395398

396-
let ffi_managed_info = FFIManagedWalletInfo::new(managed_info);
399+
let ffi_managed_info = Box::into_raw(Box::new(FFIManagedWalletInfo::new(managed_info)));
397400

398401
let result = unsafe {
399-
managed_wallet_get_utxos(&ffi_managed_info, &mut utxos_out, &mut count_out, error)
402+
managed_wallet_get_utxos(&*ffi_managed_info, &mut utxos_out, &mut count_out, error)
400403
};
401404

402405
assert!(result);
@@ -406,6 +409,7 @@ mod utxo_tests {
406409
// Clean up
407410
unsafe {
408411
utxo_array_free(utxos_out, count_out);
412+
crate::managed_wallet::managed_wallet_free(ffi_managed_info);
409413
}
410414
}
411415

@@ -464,16 +468,17 @@ mod utxo_tests {
464468
testnet_account.utxos.insert(outpoint, utxo);
465469
managed_info.accounts.insert(testnet_account);
466470

467-
let ffi_managed_info = FFIManagedWalletInfo::new(managed_info);
471+
let ffi_managed_info = Box::into_raw(Box::new(FFIManagedWalletInfo::new(managed_info)));
468472

469473
// Get UTXOs
470474
let result = unsafe {
471-
managed_wallet_get_utxos(&ffi_managed_info, &mut utxos_out, &mut count_out, error)
475+
managed_wallet_get_utxos(&*ffi_managed_info, &mut utxos_out, &mut count_out, error)
472476
};
473477
assert!(result);
474478
assert_eq!(count_out, 1);
475479
unsafe {
476480
utxo_array_free(utxos_out, count_out);
481+
crate::managed_wallet::managed_wallet_free(ffi_managed_info);
477482
}
478483
}
479484

@@ -573,22 +578,24 @@ mod utxo_tests {
573578
let mut count_out: usize = 0;
574579

575580
let managed_info = ManagedWalletInfo::new(Network::Testnet, [4u8; 32]);
576-
let ffi_managed_info = FFIManagedWalletInfo::new(managed_info);
581+
let ffi_managed_info = Box::into_raw(Box::new(FFIManagedWalletInfo::new(managed_info)));
577582

578583
// Test with null utxos_out
579584
let result = unsafe {
580-
managed_wallet_get_utxos(&ffi_managed_info, ptr::null_mut(), &mut count_out, error)
585+
managed_wallet_get_utxos(&*ffi_managed_info, ptr::null_mut(), &mut count_out, error)
581586
};
582587
assert!(!result);
583588
assert_eq!(unsafe { (*error).code }, FFIErrorCode::InvalidInput);
584589

585590
// Test with null count_out
586591
let mut utxos_out: *mut FFIUTXO = ptr::null_mut();
587592
let result = unsafe {
588-
managed_wallet_get_utxos(&ffi_managed_info, &mut utxos_out, ptr::null_mut(), error)
593+
managed_wallet_get_utxos(&*ffi_managed_info, &mut utxos_out, ptr::null_mut(), error)
589594
};
590595
assert!(!result);
591596
assert_eq!(unsafe { (*error).code }, FFIErrorCode::InvalidInput);
597+
598+
unsafe { crate::managed_wallet::managed_wallet_free(ffi_managed_info) };
592599
}
593600

594601
#[test]

0 commit comments

Comments
 (0)