diff --git a/rust/README.md b/rust/README.md index 727a820c5..0d627f6f2 100644 --- a/rust/README.md +++ b/rust/README.md @@ -18,7 +18,7 @@ To specify a specific commit see the cargo documentation [here](https://doc.rust ```rust use binaryninja::headless::Session; -use binaryninja::binaryview::{BinaryViewBase, BinaryViewExt}; +use binaryninja::binary_view::{BinaryViewBase, BinaryViewExt}; fn main() { let headless_session = Session::new().expect("Failed to initialize session"); diff --git a/rust/src/binary_view.rs b/rust/src/binary_view.rs index 824803145..691f42c86 100644 --- a/rust/src/binary_view.rs +++ b/rust/src/binary_view.rs @@ -56,7 +56,7 @@ use crate::types::{ use crate::variable::DataVariable; use crate::Endianness; use std::collections::HashMap; -use std::ffi::c_char; +use std::ffi::{c_char, c_void}; use std::ops::Range; use std::path::Path; use std::ptr::NonNull; @@ -645,17 +645,20 @@ pub trait BinaryViewExt: BinaryViewBase { .collect(); let mut result_ids: *mut *mut c_char = std::ptr::null_mut(); let mut result_names: *mut BNQualifiedName = std::ptr::null_mut(); + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let result_count = unsafe { BNDefineAnalysisTypes( self.as_ref().handle, types.as_mut_ptr(), types.len(), Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, &mut result_ids as *mut _, &mut result_names as *mut _, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; for ty in types { QualifiedNameTypeAndId::free_raw(ty); @@ -690,15 +693,18 @@ pub trait BinaryViewExt: BinaryViewBase { .map(Into::into) .map(QualifiedNameAndType::into_raw) .collect(); + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); unsafe { BNDefineUserAnalysisTypes( self.as_ref().handle, types.as_mut_ptr(), types.len(), Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; for ty in types { QualifiedNameAndType::free_raw(ty); } diff --git a/rust/src/database.rs b/rust/src/database.rs index 77a5a2288..6a43a963b 100644 --- a/rust/src/database.rs +++ b/rust/src/database.rs @@ -4,7 +4,7 @@ pub mod undo; use binaryninjacore_sys::*; use std::collections::HashMap; -use std::ffi::c_char; +use std::ffi::{c_char, c_void}; use std::fmt::Debug; use std::ptr::NonNull; @@ -94,6 +94,8 @@ impl Database { { let name_raw = name.into_bytes_with_nul(); let name_ptr = name_raw.as_ref().as_ptr() as *const c_char; + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let new_id = unsafe { BNWriteDatabaseSnapshotData( self.handle.as_ptr(), @@ -104,10 +106,11 @@ impl Database { name_ptr, data.handle.as_ptr(), auto_save, - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; SnapshotId(new_id) } diff --git a/rust/src/database/snapshot.rs b/rust/src/database/snapshot.rs index fd678c4f1..bceceb7eb 100644 --- a/rust/src/database/snapshot.rs +++ b/rust/src/database/snapshot.rs @@ -14,7 +14,7 @@ use binaryninjacore_sys::{ BNSnapshot, BNSnapshotHasAncestor, BNSnapshotHasContents, BNSnapshotHasUndo, BNSnapshotStoreData, }; -use std::ffi::c_char; +use std::ffi::{c_char, c_void}; use std::fmt; use std::fmt::{Debug, Display, Formatter}; use std::ptr::NonNull; @@ -136,14 +136,17 @@ impl Snapshot { ) -> Array { assert!(self.has_undo()); let mut count = 0; + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let result = unsafe { BNGetSnapshotUndoEntriesWithProgress( self.handle.as_ptr(), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), &mut count, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; assert!(!result.is_null()); unsafe { Array::new(result, count, ()) } } @@ -158,13 +161,16 @@ impl Snapshot { &self, progress: impl Into, ) -> Ref { + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let result = unsafe { BNReadSnapshotDataWithProgress( self.handle.as_ptr(), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; unsafe { KeyValueStore::ref_from_raw(NonNull::new(result).unwrap()) } } @@ -190,14 +196,18 @@ impl Snapshot { data: &KeyValueStore, progress: impl Into, ) -> bool { - unsafe { + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); + let success = unsafe { BNSnapshotStoreData( self.handle.as_ptr(), data.handle.as_ptr(), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ) - } + }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; + success } /// Determine if this snapshot has another as an ancestor diff --git a/rust/src/debuginfo.rs b/rust/src/debuginfo.rs index 42fa598e7..ece965b03 100644 --- a/rust/src/debuginfo.rs +++ b/rust/src/debuginfo.rs @@ -177,6 +177,8 @@ impl DebugInfoParser { existing_debug_info: Option<&DebugInfo>, progress: impl Into, ) -> Option> { + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let info: *mut BNDebugInfo = match existing_debug_info { Some(debug_info) => unsafe { BNParseDebugInfo( @@ -185,7 +187,7 @@ impl DebugInfoParser { debug_file.handle, debug_info.handle, Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, ) }, None => unsafe { @@ -195,10 +197,11 @@ impl DebugInfoParser { debug_file.handle, std::ptr::null_mut(), Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, ) }, }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; if info.is_null() { return None; } diff --git a/rust/src/file_metadata.rs b/rust/src/file_metadata.rs index 8be2c402f..8776cfba2 100644 --- a/rust/src/file_metadata.rs +++ b/rust/src/file_metadata.rs @@ -24,6 +24,7 @@ use binaryninjacore_sys::{ BNSaveAutoSnapshot, BNSetFilename, BNUndo, }; use binaryninjacore_sys::{BNCreateDatabaseWithProgress, BNOpenExistingDatabaseWithProgress}; +use std::ffi::c_void; use std::fmt::Debug; use crate::rc::*; @@ -226,15 +227,19 @@ impl FileMetadata { return false; }; - unsafe { + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); + let success = unsafe { BNCreateDatabaseWithProgress( raw_view.handle, filename_ptr, - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ptr::null_mut(), ) - } + }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; + success } pub fn save_auto_snapshot(&self) -> bool { @@ -283,15 +288,17 @@ impl FileMetadata { ) -> Result, ()> { let filename = filename.into_bytes_with_nul(); let filename_ptr = filename.as_ref().as_ptr() as *mut _; - + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let view = unsafe { BNOpenExistingDatabaseWithProgress( self.handle, filename_ptr, - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; if view.is_null() { Err(()) diff --git a/rust/src/headless.rs b/rust/src/headless.rs index 02e918fb0..6613bf908 100644 --- a/rust/src/headless.rs +++ b/rust/src/headless.rs @@ -21,7 +21,7 @@ use std::path::{Path, PathBuf}; use thiserror::Error; use crate::enterprise::release_license; -use crate::mainthread::{MainThreadAction, MainThreadHandler}; +use crate::main_thread::{MainThreadAction, MainThreadHandler}; use crate::rc::Ref; use binaryninjacore_sys::{BNInitPlugins, BNInitRepoPlugins}; use std::sync::mpsc::Sender; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 06f0381fc..9499fd512 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -73,11 +73,11 @@ pub mod interaction; pub mod linear_view; pub mod logger; pub mod low_level_il; -pub mod mainthread; +pub mod main_thread; pub mod medium_level_il; pub mod metadata; pub mod platform; -mod progress; +pub mod progress; pub mod project; pub mod rc; pub mod references; @@ -134,15 +134,18 @@ pub fn load_with_progress( ) -> Option> { let file_path = file_path.as_ref().into_bytes_with_nul(); let options = c""; + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let handle = unsafe { BNLoadFilename( file_path.as_ptr() as *mut _, true, options.as_ptr() as *mut c_char, Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; if handle.is_null() { None } else { @@ -206,16 +209,18 @@ where .as_ref() .to_vec() }; - + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let handle = unsafe { BNLoadFilename( file_path.as_ptr() as *mut _, update_analysis_and_wait, options_or_default.as_ptr() as *mut c_char, Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; if handle.is_null() { None @@ -262,16 +267,18 @@ where .as_ref() .to_vec() }; - + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let handle = unsafe { BNLoadBinaryView( bv.handle as *mut _, update_analysis_and_wait, options_or_default.as_ptr() as *mut c_char, Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; if handle.is_null() { None diff --git a/rust/src/mainthread.rs b/rust/src/main_thread.rs similarity index 100% rename from rust/src/mainthread.rs rename to rust/src/main_thread.rs diff --git a/rust/src/medium_level_il/function.rs b/rust/src/medium_level_il/function.rs index c24f862c0..c7a53b601 100644 --- a/rust/src/medium_level_il/function.rs +++ b/rust/src/medium_level_il/function.rs @@ -187,7 +187,7 @@ impl MediumLevelILFunction { /// /// # Example /// ```no_run - /// # use binaryninja::mlil::MediumLevelILFunction; + /// # use binaryninja::medium_level_il::MediumLevelILFunction; /// # use binaryninja::variable::PossibleValueSet; /// # let mlil_fun: MediumLevelILFunction = todo!(); /// let user_var_val = mlil_fun.user_var_values().iter().next().unwrap(); @@ -322,7 +322,7 @@ impl MediumLevelILFunction { /// /// # Example /// ```no_run - /// # use binaryninja::mlil::MediumLevelILFunction; + /// # use binaryninja::medium_level_il::MediumLevelILFunction; /// # use binaryninja::variable::Variable; /// # let mlil_fun: MediumLevelILFunction = todo!(); /// # let mlil_var: Variable = todo!(); diff --git a/rust/src/progress.rs b/rust/src/progress.rs index 7a4391162..605910e82 100644 --- a/rust/src/progress.rs +++ b/rust/src/progress.rs @@ -11,17 +11,12 @@ impl ProgressExecutor { } } - /// Leak the executor and return an opaque pointer. - pub fn into_raw_context(self) -> *mut c_void { - Box::into_raw(Box::new(self)) as *mut c_void - } - pub unsafe extern "C" fn cb_execute(ctx: *mut c_void, progress: usize, total: usize) -> bool { if ctx.is_null() { return true; } - let f: Box = Box::from_raw(ctx as *mut Self); - f.execute(progress, total) + let executor: *mut Self = ctx as *mut Self; + (*executor).execute(progress, total) } pub fn execute(&self, progress: usize, total: usize) -> bool { diff --git a/rust/src/project.rs b/rust/src/project.rs index 49bd32c82..3e8b45a41 100644 --- a/rust/src/project.rs +++ b/rust/src/project.rs @@ -1,7 +1,7 @@ pub mod file; pub mod folder; -use std::ffi::c_char; +use std::ffi::{c_char, c_void}; use std::fmt::Debug; use std::ptr::{null_mut, NonNull}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -39,7 +39,7 @@ impl Project { /// /// * `path` - Path to the project directory (.bnpr) /// * `name` - Name of the new project - pub fn create(path: P, name: S) -> Ref { + pub fn create(path: P, name: S) -> Option> { let path_raw = path.into_bytes_with_nul(); let name_raw = name.into_bytes_with_nul(); let handle = unsafe { @@ -48,16 +48,16 @@ impl Project { name_raw.as_ref().as_ptr() as *const c_char, ) }; - unsafe { Self::ref_from_raw(NonNull::new(handle).unwrap()) } + NonNull::new(handle).map(|h| unsafe { Self::ref_from_raw(h) }) } /// Open an existing project /// /// * `path` - Path to the project directory (.bnpr) or project metadata file (.bnpm) - pub fn open_project(path: P) -> Ref { + pub fn open_project(path: P) -> Option> { let path_raw = path.into_bytes_with_nul(); let handle = unsafe { BNOpenProject(path_raw.as_ref().as_ptr() as *const c_char) }; - unsafe { Self::ref_from_raw(NonNull::new(handle).unwrap()) } + NonNull::new(handle).map(|h| unsafe { Self::ref_from_raw(h) }) } /// Check if the project is currently open @@ -207,16 +207,18 @@ impl Project { let path_raw = path.into_bytes_with_nul(); let description_raw = description.into_bytes_with_nul(); let parent_ptr = parent.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); - + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); unsafe { let result = BNProjectCreateFolderFromPath( self.handle.as_ptr(), path_raw.as_ref().as_ptr() as *const c_char, parent_ptr, description_raw.as_ref().as_ptr() as *const c_char, - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ); + let _ = Box::from_raw(leaked_boxed_progress); Ok(ProjectFolder::ref_from_raw(NonNull::new(result).ok_or(())?)) } } @@ -320,14 +322,17 @@ impl Project { folder: &ProjectFolder, progress: impl Into, ) -> Result<(), ()> { + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let result = unsafe { BNProjectDeleteFolder( self.handle.as_ptr(), folder.handle.as_ptr(), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; if result { Ok(()) } else { @@ -390,6 +395,8 @@ impl Project { let name_raw = name.into_bytes_with_nul(); let description_raw = description.into_bytes_with_nul(); let folder_ptr = folder.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); unsafe { let result = BNProjectCreateFileFromPath( self.handle.as_ptr(), @@ -397,9 +404,10 @@ impl Project { folder_ptr, name_raw.as_ref().as_ptr() as *const c_char, description_raw.as_ref().as_ptr() as *const c_char, - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ); + let _ = Box::from_raw(leaked_boxed_progress); Ok(ProjectFile::ref_from_raw(NonNull::new(result).ok_or(())?)) } } @@ -469,6 +477,8 @@ impl Project { let description_raw = description.into_bytes_with_nul(); let id_raw = id.into_bytes_with_nul(); let folder_ptr = folder.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); unsafe { let result = BNProjectCreateFileFromPathUnsafe( self.handle.as_ptr(), @@ -478,9 +488,10 @@ impl Project { description_raw.as_ref().as_ptr() as *const c_char, id_raw.as_ref().as_ptr() as *const c_char, systime_to_bntime(creation_time).unwrap(), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ); + let _ = Box::from_raw(leaked_boxed_progress); Ok(ProjectFile::ref_from_raw(NonNull::new(result).ok_or(())?)) } } @@ -533,6 +544,8 @@ impl Project { let name_raw = name.into_bytes_with_nul(); let description_raw = description.into_bytes_with_nul(); let folder_ptr = folder.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); unsafe { let result = BNProjectCreateFile( self.handle.as_ptr(), @@ -541,9 +554,10 @@ impl Project { folder_ptr, name_raw.as_ref().as_ptr() as *const c_char, description_raw.as_ref().as_ptr() as *const c_char, - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ); + let _ = Box::from_raw(leaked_boxed_progress); Ok(ProjectFile::ref_from_raw(NonNull::new(result).ok_or(())?)) } } @@ -610,6 +624,8 @@ impl Project { let description_raw = description.into_bytes_with_nul(); let id_raw = id.into_bytes_with_nul(); let folder_ptr = folder.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); unsafe { let result = BNProjectCreateFileUnsafe( self.handle.as_ptr(), @@ -620,19 +636,20 @@ impl Project { description_raw.as_ref().as_ptr() as *const c_char, id_raw.as_ref().as_ptr() as *const c_char, systime_to_bntime(creation_time).unwrap(), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ); + let _ = Box::from_raw(leaked_boxed_progress); Ok(ProjectFile::ref_from_raw(NonNull::new(result).ok_or(())?)) } } /// Get a list of files in the project - pub fn files(&self) -> Result, ()> { + pub fn files(&self) -> Array { let mut count = 0; let result = unsafe { BNProjectGetFiles(self.handle.as_ptr(), &mut count) }; assert!(!result.is_null()); - Ok(unsafe { Array::new(result, count, ()) }) + unsafe { Array::new(result, count, ()) } } /// Retrieve a file in the project by unique `id` diff --git a/rust/src/project/file.rs b/rust/src/project/file.rs index dfa19a7dc..5071dd50b 100644 --- a/rust/src/project/file.rs +++ b/rust/src/project/file.rs @@ -90,9 +90,9 @@ impl ProjectFile { } /// Get the folder that contains this file - pub fn folder(&self) -> Option { + pub fn folder(&self) -> Option> { let result = unsafe { BNProjectFileGetFolder(self.handle.as_ptr()) }; - NonNull::new(result).map(|handle| unsafe { ProjectFolder::from_raw(handle) }) + NonNull::new(result).map(|handle| unsafe { ProjectFolder::ref_from_raw(handle) }) } /// Set the folder that contains this file diff --git a/rust/src/project/folder.rs b/rust/src/project/folder.rs index 01d9f992a..ea2789dd3 100644 --- a/rust/src/project/folder.rs +++ b/rust/src/project/folder.rs @@ -8,7 +8,7 @@ use binaryninjacore_sys::{ BNProjectFolderGetName, BNProjectFolderGetParent, BNProjectFolderGetProject, BNProjectFolderSetDescription, BNProjectFolderSetName, BNProjectFolderSetParent, }; -use std::ffi::c_char; +use std::ffi::{c_char, c_void}; use std::fmt::Debug; use std::ptr::{null_mut, NonNull}; @@ -27,9 +27,9 @@ impl ProjectFolder { } /// Get the project that owns this folder - pub fn project(&self) -> Project { + pub fn project(&self) -> Ref { unsafe { - Project::from_raw( + Project::ref_from_raw( NonNull::new(BNProjectFolderGetProject(self.handle.as_ptr())).unwrap(), ) } @@ -102,14 +102,18 @@ impl ProjectFolder { S: BnStrCompatible, { let dest_raw = dest.into_bytes_with_nul(); - unsafe { + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); + let success = unsafe { BNProjectFolderExport( self.handle.as_ptr(), dest_raw.as_ref().as_ptr() as *const c_char, - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, Some(ProgressExecutor::cb_execute), ) - } + }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; + success } } diff --git a/rust/src/type_archive.rs b/rust/src/type_archive.rs index 1930b3372..8d2671580 100644 --- a/rust/src/type_archive.rs +++ b/rust/src/type_archive.rs @@ -836,7 +836,8 @@ impl TypeArchive { let mut conflicts_errors_count = 0; let mut result = std::ptr::null_mut(); - + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let success = unsafe { BNTypeArchiveMergeSnapshots( self.handle.as_ptr(), @@ -850,9 +851,10 @@ impl TypeArchive { &mut conflicts_errors_count, &mut result, Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; if success { assert!(!result.is_null()); Ok(unsafe { BnString::from_raw(result) }) diff --git a/rust/src/type_container.rs b/rust/src/type_container.rs index 1aa578804..e060d87b9 100644 --- a/rust/src/type_container.rs +++ b/rust/src/type_container.rs @@ -16,7 +16,7 @@ use crate::type_parser::{TypeParserError, TypeParserResult}; use crate::types::{QualifiedName, QualifiedNameAndType, Type}; use binaryninjacore_sys::*; use std::collections::HashMap; -use std::ffi::c_char; +use std::ffi::{c_char, c_void}; use std::fmt::{Debug, Formatter}; use std::ptr::NonNull; @@ -113,6 +113,8 @@ impl TypeContainer { let mut result_names = std::ptr::null_mut(); let mut result_ids = std::ptr::null_mut(); let mut result_count = 0; + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let success = unsafe { BNTypeContainerAddTypes( self.handle.as_ptr(), @@ -120,12 +122,13 @@ impl TypeContainer { raw_types.as_mut_ptr(), raw_types.len(), Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, &mut result_names, &mut result_ids, &mut result_count, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; for name in raw_names { QualifiedName::free_raw(name); } diff --git a/rust/src/update.rs b/rust/src/update.rs index 85f5002dd..db930b2d5 100644 --- a/rust/src/update.rs +++ b/rust/src/update.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -use std::ffi::c_char; +use std::ffi::{c_char, c_void}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use crate::progress::ProgressExecutor; @@ -146,14 +146,17 @@ impl UpdateChannel { progress: impl Into, ) -> Result { let mut errors = std::ptr::null_mut(); + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let result = unsafe { BNUpdateToLatestVersion( self.name.as_ptr() as *const c_char, &mut errors, Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; if !errors.is_null() { Err(unsafe { BnString::from_raw(errors) }) } else { @@ -171,15 +174,18 @@ impl UpdateChannel { progress: impl Into, ) -> Result { let mut errors = std::ptr::null_mut(); + let boxed_progress = Box::new(progress.into()); + let leaked_boxed_progress = Box::into_raw(boxed_progress); let result = unsafe { BNUpdateToVersion( self.name.as_ptr() as *const c_char, version.version.as_ptr() as *const c_char, &mut errors, Some(ProgressExecutor::cb_execute), - progress.into().into_raw_context(), + leaked_boxed_progress as *mut c_void, ) }; + let _ = unsafe { Box::from_raw(leaked_boxed_progress) }; if !errors.is_null() { Err(unsafe { BnString::from_raw(errors) }) } else { diff --git a/rust/tests/mainthread.rs b/rust/tests/mainthread.rs index 3ca236f81..f74414d55 100644 --- a/rust/tests/mainthread.rs +++ b/rust/tests/mainthread.rs @@ -18,7 +18,7 @@ fn test_not_main_thread(_session: &Session) { #[rstest] fn test_main_thread_different(_session: &Session) { let calling_thread = std::thread::current(); - binaryninja::mainthread::execute_on_main_thread_and_wait(move || { + binaryninja::main_thread::execute_on_main_thread_and_wait(move || { let main_thread = std::thread::current(); assert_ne!( calling_thread.id(), diff --git a/rust/tests/project.rs b/rust/tests/project.rs index 9f757f2fe..cc41c11e6 100644 --- a/rust/tests/project.rs +++ b/rust/tests/project.rs @@ -24,7 +24,7 @@ fn create_delete_empty(_session: &Session) { let project_name = "create_delete_empty_project"; let project_path = unique_project(project_name); // create the project - let project = Project::create(&project_path, project_name); + let project = Project::create(&project_path, project_name).expect("Failed to create project"); project.open().unwrap(); assert!(project.is_open()); @@ -51,7 +51,7 @@ fn create_close_open_close(_session: &Session) { let project_name = "create_close_open_close"; let project_path = unique_project(project_name); // create the project - let project = Project::create(&project_path, project_name); + let project = Project::create(&project_path, project_name).expect("Failed to create project"); project.open().unwrap(); // get the project id @@ -61,7 +61,7 @@ fn create_close_open_close(_session: &Session) { project.close().unwrap(); drop(project); - let project = Project::open_project(&project_path); + let project = Project::open_project(&project_path).expect("Failed to open project"); // assert same id let new_id = project.id(); assert_eq!(id, new_id); @@ -76,10 +76,10 @@ fn create_close_open_close(_session: &Session) { #[rstest] fn modify_project(_session: &Session) { - let project_name = "modify_project"; + let project_name = "modify_project_project"; let project_path = unique_project(project_name); // create the project - let project = Project::create(&project_path, project_name); + let project = Project::create(&project_path, project_name).expect("Failed to create project"); project.open().unwrap(); // get project id @@ -248,12 +248,12 @@ fn modify_project(_session: &Session) { } .unwrap(); - assert_eq!(project.files().unwrap().len(), 10); + assert_eq!(project.files().len(), 10); let file_a = project.file_by_id(file_8.id()).unwrap(); let file_b = project.file_by_path(file_7.path_on_disk()).unwrap(); project.delete_file(&file_a); project.delete_file(&file_b); - assert_eq!(project.files().unwrap().len(), 8); + assert_eq!(project.files().len(), 8); drop(file_8); drop(file_7); @@ -268,7 +268,7 @@ fn modify_project(_session: &Session) { drop(folder_3); // reopen the project and verify the information store on it - let project = Project::open_project(&project_path); + let project = Project::open_project(&project_path).expect("Failed to open project"); // assert same id assert_eq!(id, project.id()); @@ -317,7 +317,7 @@ fn modify_project(_session: &Session) { ("input_1", &input_file_1_data[..], None, None), ("input_2", &input_file_2_data[..], None, None), ]; - for file in project.files().unwrap().iter() { + for file in project.files().iter() { let found = files.iter().find(|f| file.name().as_str() == f.0).unwrap(); if let Some(id) = found.2 { assert_eq!(file.id().as_str(), id);