Skip to content

Commit 2aa843e

Browse files
fix: improve memory management in FFI progress callbacks
This commit enhances memory management in the FFI layer by ensuring that the stage_message is properly moved out of the FFIDetailedSyncProgress struct before destruction. This change prevents potential double-free issues and ensures that heap-allocated strings are correctly freed, addressing memory leak concerns during progress callbacks.
1 parent 5485ea9 commit 2aa843e

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

dash-spv-ffi/src/client.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -812,8 +812,8 @@ pub unsafe extern "C" fn dash_spv_ffi_client_sync_to_tip_with_progress(
812812
SyncStage::Complete | SyncStage::Failed(_)
813813
);
814814

815-
// Create FFI progress
816-
let ffi_progress = Box::new(FFIDetailedSyncProgress::from(progress));
815+
// Create FFI progress (stack-allocated to avoid double-free issues)
816+
let mut ffi_progress = FFIDetailedSyncProgress::from(progress);
817817

818818
// Call the callback using the registry
819819
{
@@ -830,13 +830,24 @@ pub unsafe extern "C" fn dash_spv_ffi_client_sync_to_tip_with_progress(
830830
// SAFETY: The callback and user_data are safely stored in the registry
831831
// and accessed through thread-safe mechanisms. The registry ensures
832832
// proper lifetime management without raw pointer passing across threads.
833-
callback(ffi_progress.as_ref(), *user_data);
833+
callback(&ffi_progress, *user_data);
834834

835835
// Free any heap-allocated strings inside the progress struct
836836
// to avoid leaking per-callback allocations (e.g., stage_message).
837+
// Move stage_message out of the struct to avoid double-free.
837838
unsafe {
839+
// Move stage_message out of the struct (not using ptr::read to avoid double-free)
840+
let stage_message = std::mem::replace(
841+
&mut ffi_progress.stage_message,
842+
crate::types::FFIString {
843+
ptr: std::ptr::null_mut(),
844+
length: 0,
845+
},
846+
);
838847
// Destroy stage_message allocated in FFIDetailedSyncProgress::from
839-
crate::types::dash_spv_ffi_string_destroy(std::ptr::read(&ffi_progress.stage_message));
848+
crate::types::dash_spv_ffi_string_destroy(stage_message);
849+
// Prevent Drop from running on the struct to avoid re-freeing
850+
std::mem::forget(ffi_progress);
840851
}
841852
}
842853
}

0 commit comments

Comments
 (0)