Skip to content

Commit 534627a

Browse files
committed
[Rust] Take download callbacks by reference to avoid boxing
1 parent abfd08f commit 534627a

File tree

4 files changed

+43
-13
lines changed

4 files changed

+43
-13
lines changed

plugins/dwarf/dwarf_import/src/helpers.rs

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

0 commit comments

Comments
 (0)