Skip to content

Commit 8f5bb19

Browse files
author
vatsalkeshav
committed
remove usage of free,malloc
1 parent 4f6fb20 commit 8f5bb19

1 file changed

Lines changed: 27 additions & 33 deletions

File tree

src/rust/src/xds/handlers.rs

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ pub mod bindings {
2626
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
2727
}
2828

29+
use std::alloc::{self, Layout};
2930
use std::ffi::CString;
31+
use std::mem::{align_of, size_of};
3032
use std::os::raw::c_void;
3133
use std::ptr::null_mut;
3234
use std::sync::atomic::Ordering;
3335

34-
use crate::bindings::{cc_subtitle, eia608_screen, realloc};
36+
use crate::bindings::{cc_subtitle, eia608_screen};
3537

3638
use lib_ccxr::debug;
3739
use lib_ccxr::info;
@@ -42,31 +44,8 @@ use lib_ccxr::util::log::{hex_dump, send_gui, DebugMessageFlag, GuiXdsMessage};
4244
use crate::xds::constants::*;
4345
use crate::xds::types::*;
4446

45-
extern "C" {
46-
fn malloc(size: usize) -> *mut c_void;
47-
fn free(ptr: *mut c_void);
48-
}
49-
5047
// --- helper func ---
5148

52-
/// Frees a pointer and sets it to null.
53-
///
54-
/// Converts the raw pointer back into a `Box` to deallocate the memory,
55-
/// then sets the original pointer to null to prevent use-after-free.
56-
///
57-
/// # Safety
58-
/// - The pointer must have been originally allocated by Rust's `Box::into_raw`
59-
/// or equivalent. Using this with C-allocated memory will cause undefined behavior.
60-
/// - The pointer must not be used after this call.
61-
pub fn freep<T>(ptr: &mut *mut T) {
62-
unsafe {
63-
if !ptr.is_null() {
64-
free(*ptr as *mut c_void);
65-
*ptr = null_mut();
66-
}
67-
}
68-
}
69-
7049
/// Helper function to copy String into i8 array
7150
fn string_to_i8_array(s: &str, arr: &mut [i8]) {
7251
let bytes = s.as_bytes();
@@ -94,7 +73,6 @@ fn i8_array_to_string(arr: &[i8]) -> String {
9473
/// Writes an XDS string to the subtitle output buffer.
9574
///
9675
/// # Safety
97-
/// - `sub.data` must be a valid pointer previously allocated by C's malloc/realloc, or null.
9876
/// - The caller must ensure `sub` and `ctx` remain valid for the duration of the call.
9977
/// - The returned `xds_str` pointer in the screen data must be freed with `CString::from_raw`.
10078
pub unsafe fn write_xds_string(
@@ -103,28 +81,44 @@ pub unsafe fn write_xds_string(
10381
p: String,
10482
ts_start_of_xds: i64,
10583
) -> Result<(), ()> {
84+
let c_str = CString::new(p).map_err(|_| ())?;
85+
let len = c_str.as_bytes().len(); // length w/o null terminator - matching C's vsnprintf return
86+
let alloc_len = len + 1; // allocate space for null terminator
87+
10688
let new_size = (sub.nb_data + 1) as usize * size_of::<eia608_screen>();
107-
let new_data =
108-
unsafe { realloc(sub.data as *mut c_void, new_size as u64) as *mut eia608_screen };
89+
let screen_align = align_of::<eia608_screen>();
90+
let new_data = unsafe {
91+
if sub.data.is_null() {
92+
let layout = Layout::from_size_align_unchecked(new_size, screen_align);
93+
alloc::alloc(layout) as *mut eia608_screen
94+
} else {
95+
let old_size = sub.nb_data as usize * size_of::<eia608_screen>();
96+
let old_layout = Layout::from_size_align_unchecked(old_size, screen_align);
97+
alloc::realloc(sub.data as *mut u8, old_layout, new_size) as *mut eia608_screen
98+
}
99+
};
109100
if new_data.is_null() {
110-
freep(&mut sub.data);
101+
if !sub.data.is_null() && sub.nb_data > 0 {
102+
let old_size = sub.nb_data as usize * size_of::<eia608_screen>();
103+
let old_layout = Layout::from_size_align_unchecked(old_size, screen_align);
104+
alloc::dealloc(sub.data as *mut u8, old_layout);
105+
sub.data = null_mut();
106+
}
111107
sub.nb_data = 0;
112108
info!("No Memory left");
113109
return Err(());
114110
}
115111
sub.data = new_data as *mut c_void;
116112
sub.datatype = 0;
117113
let data_element = &mut *new_data.add(sub.nb_data as usize);
118-
let c_str = CString::new(p).map_err(|_| ())?;
119114

120-
let len = c_str.as_bytes().len(); // length w/o null terminator - matching C's vsnprintf return
121-
let alloc_len = len + 1; // allocate space for null terminator
122-
let ptr = unsafe { malloc(alloc_len) as *mut i8 }; // fixing c/rust mem mismatch
115+
let str_layout = Layout::from_size_align(alloc_len, 1).map_err(|_| ())?;
116+
let ptr = unsafe { alloc::alloc(str_layout) as *mut i8 };
123117
if ptr.is_null() {
124118
return Err(());
125119
}
126120
unsafe {
127-
std::ptr::copy_nonoverlapping(c_str.as_ptr(), ptr, alloc_len); // copy including null terminator
121+
std::ptr::copy_nonoverlapping(c_str.as_ptr(), ptr, alloc_len);
128122
}
129123

130124
data_element.format = 2;

0 commit comments

Comments
 (0)