Skip to content

Commit 3667543

Browse files
authored
Fix memory leak in owned_to_vec (#773)
1 parent e0f3a25 commit 3667543

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

src/bytes.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,15 +1141,15 @@ unsafe fn owned_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes
11411141
}
11421142
}
11431143

1144-
unsafe fn owned_to_vec(_data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
1144+
unsafe fn owned_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
11451145
let slice = slice::from_raw_parts(ptr, len);
1146-
slice.to_vec()
1146+
let vec = slice.to_vec();
1147+
owned_drop_impl(data.load(Ordering::Relaxed));
1148+
vec
11471149
}
11481150

11491151
unsafe fn owned_to_mut(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> BytesMut {
1150-
let bytes_mut = BytesMut::from_vec(owned_to_vec(data, ptr, len));
1151-
owned_drop_impl(data.load(Ordering::Relaxed));
1152-
bytes_mut
1152+
BytesMut::from_vec(owned_to_vec(data, ptr, len))
11531153
}
11541154

11551155
unsafe fn owned_is_unique(_data: &AtomicPtr<()>) -> bool {
@@ -1161,6 +1161,10 @@ unsafe fn owned_drop_impl(owned: *mut ()) {
11611161
let ref_cnt = &(*lifetime).ref_cnt;
11621162

11631163
let old_cnt = ref_cnt.fetch_sub(1, Ordering::Release);
1164+
debug_assert!(
1165+
old_cnt > 0 && old_cnt <= usize::MAX >> 1,
1166+
"expected non-zero refcount and no underflow"
1167+
);
11641168
if old_cnt != 1 {
11651169
return;
11661170
}

tests/test_bytes.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,6 +1619,19 @@ fn owned_to_vec() {
16191619
assert_eq!(drop_counter.get(), 1);
16201620
}
16211621

1622+
#[test]
1623+
fn owned_into_vec() {
1624+
let drop_counter = SharedAtomicCounter::new();
1625+
let buf: [u8; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
1626+
let owner = OwnedTester::new(buf, drop_counter.clone());
1627+
let b1 = Bytes::from_owner(owner);
1628+
1629+
let v1: Vec<u8> = b1.into();
1630+
assert_eq!(&v1[..], &buf[..]);
1631+
// into() vec will copy out of the owner and drop it
1632+
assert_eq!(drop_counter.get(), 1);
1633+
}
1634+
16221635
#[test]
16231636
#[cfg_attr(not(panic = "unwind"), ignore)]
16241637
fn owned_safe_drop_on_as_ref_panic() {

0 commit comments

Comments
 (0)