Skip to content

Commit 2b9bb43

Browse files
kalcutterrotty
authored andcommitted
Fix broken Message::from(Box<[u8]>)
The size information was not preserved when handing the memory back to the Rust allocator for deallocation.
1 parent f7566bd commit 2b9bb43

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

src/message.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ impl fmt::Debug for Message {
3737
}
3838
}
3939

40-
unsafe extern "C" fn drop_msg_content_box(data: *mut c_void, _hint: *mut c_void) {
41-
let _ = Box::from_raw(data as *mut u8);
40+
unsafe extern "C" fn drop_msg_data_box(data: *mut c_void, hint: *mut c_void) {
41+
let _ = Box::from_raw(slice::from_raw_parts_mut(data as *mut u8, hint as usize));
4242
}
4343

4444
impl Message {
@@ -204,8 +204,8 @@ impl From<Vec<u8>> for Message {
204204
impl From<Box<[u8]>> for Message {
205205
/// Construct a message from a boxed slice without copying the data.
206206
fn from(data: Box<[u8]>) -> Self {
207-
let n = data.len();
208-
if n == 0 {
207+
let len = data.len();
208+
if len == 0 {
209209
return Message::new();
210210
}
211211
let raw = Box::into_raw(data);
@@ -214,9 +214,9 @@ impl From<Box<[u8]>> for Message {
214214
zmq_sys::zmq_msg_init_data(
215215
msg,
216216
raw as *mut c_void,
217-
n,
218-
Some(drop_msg_content_box),
219-
ptr::null_mut(),
217+
len,
218+
Some(drop_msg_data_box),
219+
len as *mut c_void,
220220
)
221221
})
222222
}

tests/message_from_boxed_slice.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use std::alloc::{GlobalAlloc, Layout, System};
2+
use std::ptr;
3+
use std::sync::atomic::{AtomicPtr, Ordering};
4+
5+
struct Allocator;
6+
7+
static CHECK_PTR: AtomicPtr<u8> = AtomicPtr::new(ptr::null_mut());
8+
9+
unsafe impl GlobalAlloc for Allocator {
10+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
11+
System.alloc(layout)
12+
}
13+
14+
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
15+
if ptr == CHECK_PTR.load(Ordering::SeqCst) {
16+
assert_eq!(layout, Layout::new::<[u8; 42]>());
17+
CHECK_PTR.store(ptr::null_mut(), Ordering::SeqCst);
18+
}
19+
System.dealloc(ptr, layout);
20+
}
21+
}
22+
23+
#[global_allocator]
24+
static A: Allocator = Allocator;
25+
26+
#[test]
27+
fn message_from_boxed_slice() {
28+
let mut b: Box<[u8]> = Box::new([0u8; 42]);
29+
CHECK_PTR.store(b.as_mut_ptr() as *mut u8, Ordering::SeqCst);
30+
let _ = zmq::Message::from(b);
31+
}

0 commit comments

Comments
 (0)