diff options
| author | Mason Reed <mason@vector35.com> | 2025-08-03 16:59:02 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-08-06 21:04:39 -0400 |
| commit | 534627a04c77aa6791be25ad04deefa9b37034f5 (patch) | |
| tree | 00d8ec654e7bc1c584207aaa3c9de8b1e9f48710 | |
| parent | abfd08fe0d92120019c2db275537eb816dd5c3f7 (diff) | |
[Rust] Take download callbacks by reference to avoid boxing
| -rw-r--r-- | plugins/dwarf/dwarf_import/src/helpers.rs | 2 | ||||
| -rw-r--r-- | plugins/pdb-ng/src/lib.rs | 2 | ||||
| -rw-r--r-- | rust/src/download_provider.rs | 18 | ||||
| -rw-r--r-- | rust/tests/download_provider.rs | 34 |
4 files changed, 43 insertions, 13 deletions
diff --git a/plugins/dwarf/dwarf_import/src/helpers.rs b/plugins/dwarf/dwarf_import/src/helpers.rs index f2f67170..fdf4e038 100644 --- a/plugins/dwarf/dwarf_import/src/helpers.rs +++ b/plugins/dwarf/dwarf_import/src/helpers.rs @@ -452,7 +452,7 @@ pub(crate) fn download_debug_info( "GET", &artifact_url, vec![], - DownloadInstanceInputOutputCallbacks { + &DownloadInstanceInputOutputCallbacks { read: None, write: Some(Box::new(write)), progress: None, diff --git a/plugins/pdb-ng/src/lib.rs b/plugins/pdb-ng/src/lib.rs index 63efd56c..cad1ada0 100644 --- a/plugins/pdb-ng/src/lib.rs +++ b/plugins/pdb-ng/src/lib.rs @@ -195,7 +195,7 @@ fn read_from_sym_store(bv: &BinaryView, path: &str) -> Result<(bool, Vec<u8>)> { "GET", path, vec![], - DownloadInstanceInputOutputCallbacks { + &DownloadInstanceInputOutputCallbacks { read: None, write: Some(Box::new(write)), progress: None, diff --git a/rust/src/download_provider.rs b/rust/src/download_provider.rs index 9fd803a7..b0c25b42 100644 --- a/rust/src/download_provider.rs +++ b/rust/src/download_provider.rs @@ -134,14 +134,13 @@ impl DownloadInstance { pub fn perform_request( &mut self, url: &str, - callbacks: DownloadInstanceOutputCallbacks, + callbacks: &DownloadInstanceOutputCallbacks, ) -> Result<(), String> { - let callbacks = Box::into_raw(Box::new(callbacks)); let mut cbs = BNDownloadInstanceOutputCallbacks { writeCallback: Some(Self::o_write_callback), - writeContext: callbacks as *mut c_void, + writeContext: callbacks as *const _ as *mut c_void, progressCallback: Some(Self::o_progress_callback), - progressContext: callbacks as *mut c_void, + progressContext: callbacks as *const _ as *mut c_void, }; let url_raw = url.to_cstr(); @@ -153,8 +152,6 @@ impl DownloadInstance { ) }; - // Drop it - unsafe { drop(Box::from_raw(callbacks)) }; if result < 0 { Err(self.get_error()) } else { @@ -206,7 +203,7 @@ impl DownloadInstance { method: &str, url: &str, headers: I, - callbacks: DownloadInstanceInputOutputCallbacks, + callbacks: &DownloadInstanceInputOutputCallbacks, ) -> Result<DownloadResponse, String> where I: IntoIterator<Item = (String, String)>, @@ -226,14 +223,13 @@ impl DownloadInstance { header_value_ptrs.push(value.as_ptr()); } - let callbacks = Box::into_raw(Box::new(callbacks)); let mut cbs = BNDownloadInstanceInputOutputCallbacks { readCallback: Some(Self::i_read_callback), - readContext: callbacks as *mut c_void, + readContext: callbacks as *const _ as *mut c_void, writeCallback: Some(Self::i_write_callback), - writeContext: callbacks as *mut c_void, + writeContext: callbacks as *const _ as *mut c_void, progressCallback: Some(Self::i_progress_callback), - progressContext: callbacks as *mut c_void, + progressContext: callbacks as *const _ as *mut c_void, }; let mut response: *mut BNDownloadInstanceResponse = null_mut(); diff --git a/rust/tests/download_provider.rs b/rust/tests/download_provider.rs new file mode 100644 index 00000000..f3b62263 --- /dev/null +++ b/rust/tests/download_provider.rs @@ -0,0 +1,34 @@ +use binaryninja::download_provider::{DownloadInstanceInputOutputCallbacks, DownloadProvider}; +use binaryninja::headless::Session; +use std::sync::mpsc; + +#[test] +fn test_download_provider() { + let _session = Session::new().expect("Failed to initialize session"); + let provider = DownloadProvider::try_default().expect("Couldn't get default download provider"); + let mut inst = provider + .create_instance() + .expect("Couldn't create download instance"); + let (tx, rx) = mpsc::channel(); + let write = move |data: &[u8]| -> usize { + tx.send(data.to_vec()).expect("Couldn't send data"); + data.len() + }; + let result = inst + .perform_custom_request( + "GET", + "http://httpbin.org/get", + vec![], + &DownloadInstanceInputOutputCallbacks { + read: None, + write: Some(Box::new(write)), + progress: None, + }, + ) + .expect("Couldn't perform custom request"); + assert_eq!(result.status_code, 200); + let written = rx.recv().expect("Couldn't receive data"); + let written_str = String::from_utf8(written).expect("Couldn't convert data to string"); + println!("{}", written_str); + assert!(written_str.contains("httpbin.org/get")); +} |
