Skip to content

Commit 966097b

Browse files
committed
[Rust] Take download callbacks by reference to avoid boxing
1 parent 1455831 commit 966097b

File tree

4 files changed

+46
-15
lines changed

4 files changed

+46
-15
lines changed

plugins/dwarf/dwarf_import/src/helpers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use binaryninja::file_metadata::FileMetadata;
2222
use binaryninja::Endianness;
2323
use binaryninja::{
2424
binary_view::{BinaryView, BinaryViewExt},
25-
download_provider::{DownloadInstanceInputOutputCallbacks, DownloadProvider},
25+
download_provider::{DownloadProvider, DownloadInstanceInputOutputCallbacks},
2626
rc::Ref,
2727
settings::Settings,
2828
};
@@ -452,7 +452,7 @@ pub(crate) fn download_debug_info(
452452
"GET",
453453
&artifact_url,
454454
vec![],
455-
DownloadInstanceInputOutputCallbacks {
455+
&DownloadInstanceInputOutputCallbacks {
456456
read: None,
457457
write: Some(Box::new(write)),
458458
progress: None,

plugins/pdb-ng/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use pdb::PDB;
2626

2727
use binaryninja::binary_view::{BinaryView, BinaryViewBase, BinaryViewExt};
2828
use binaryninja::debuginfo::{CustomDebugInfoParser, DebugInfo, DebugInfoParser};
29-
use binaryninja::download_provider::{DownloadInstanceInputOutputCallbacks, DownloadProvider};
29+
use binaryninja::download_provider::{DownloadProvider, DownloadInstanceInputOutputCallbacks};
3030
use binaryninja::interaction::{MessageBoxButtonResult, MessageBoxButtonSet};
3131
use binaryninja::logger::Logger;
3232
use binaryninja::settings::{QueryOptions, Settings};
@@ -195,7 +195,7 @@ fn read_from_sym_store(bv: &BinaryView, path: &str) -> Result<(bool, Vec<u8>)> {
195195
"GET",
196196
path,
197197
vec![],
198-
DownloadInstanceInputOutputCallbacks {
198+
&DownloadInstanceInputOutputCallbacks {
199199
read: None,
200200
write: Some(Box::new(write)),
201201
progress: None,

rust/src/download_provider.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,13 @@ impl DownloadInstance {
134134
pub fn perform_request(
135135
&mut self,
136136
url: &str,
137-
callbacks: DownloadInstanceOutputCallbacks,
137+
callbacks: &DownloadInstanceOutputCallbacks,
138138
) -> Result<(), String> {
139-
let callbacks = Box::into_raw(Box::new(callbacks));
140139
let mut cbs = BNDownloadInstanceOutputCallbacks {
141140
writeCallback: Some(Self::o_write_callback),
142-
writeContext: callbacks as *mut c_void,
141+
writeContext: callbacks as *const _ as *mut c_void,
143142
progressCallback: Some(Self::o_progress_callback),
144-
progressContext: callbacks as *mut c_void,
143+
progressContext: callbacks as *const _ as *mut c_void,
145144
};
146145

147146
let url_raw = url.to_cstr();
@@ -153,8 +152,6 @@ impl DownloadInstance {
153152
)
154153
};
155154

156-
// Drop it
157-
unsafe { drop(Box::from_raw(callbacks)) };
158155
if result < 0 {
159156
Err(self.get_error())
160157
} else {
@@ -206,7 +203,7 @@ impl DownloadInstance {
206203
method: &str,
207204
url: &str,
208205
headers: I,
209-
callbacks: DownloadInstanceInputOutputCallbacks,
206+
callbacks: &DownloadInstanceInputOutputCallbacks,
210207
) -> Result<DownloadResponse, String>
211208
where
212209
I: IntoIterator<Item = (String, String)>,
@@ -226,14 +223,13 @@ impl DownloadInstance {
226223
header_value_ptrs.push(value.as_ptr());
227224
}
228225

229-
let callbacks = Box::into_raw(Box::new(callbacks));
230226
let mut cbs = BNDownloadInstanceInputOutputCallbacks {
231227
readCallback: Some(Self::i_read_callback),
232-
readContext: callbacks as *mut c_void,
228+
readContext: callbacks as *const _ as *mut c_void,
233229
writeCallback: Some(Self::i_write_callback),
234-
writeContext: callbacks as *mut c_void,
230+
writeContext: callbacks as *const _ as *mut c_void,
235231
progressCallback: Some(Self::i_progress_callback),
236-
progressContext: callbacks as *mut c_void,
232+
progressContext: callbacks as *const _ as *mut c_void,
237233
};
238234

239235
let mut response: *mut BNDownloadInstanceResponse = null_mut();

rust/tests/download_provider.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use binaryninja::download_provider::{DownloadProvider, DownloadInstanceInputOutputCallbacks};
2+
use binaryninja::headless::Session;
3+
use std::sync::mpsc;
4+
5+
#[test]
6+
fn test_download_provider() {
7+
let _session = Session::new().expect("Failed to initialize session");
8+
let provider =
9+
DownloadProvider::try_default().expect("Couldn't get default download provider");
10+
let mut inst = provider
11+
.create_instance()
12+
.expect("Couldn't create download instance");
13+
let (tx, rx) = mpsc::channel();
14+
let write = move |data: &[u8]| -> usize {
15+
tx.send(data.to_vec()).expect("Couldn't send data");
16+
data.len()
17+
};
18+
let result = inst
19+
.perform_custom_request(
20+
"GET",
21+
"http://httpbin.org/get",
22+
vec![],
23+
&DownloadInstanceInputOutputCallbacks {
24+
read: None,
25+
write: Some(Box::new(write)),
26+
progress: None,
27+
},
28+
)
29+
.expect("Couldn't perform custom request");
30+
assert_eq!(result.status_code, 200);
31+
let written = rx.recv().expect("Couldn't receive data");
32+
let written_str = String::from_utf8(written).expect("Couldn't convert data to string");
33+
println!("{}", written_str);
34+
assert!(written_str.contains("httpbin.org/get"));
35+
}

0 commit comments

Comments
 (0)