From 67437b62d541911a42438a121e437292a0614eaa Mon Sep 17 00:00:00 2001 From: rhythmcache <153998419+rhythmcache@users.noreply.github.com> Date: Fri, 20 Feb 2026 09:46:55 +0530 Subject: [PATCH 1/2] Fix allocator mismatch when freeing Rust allocated inputfile strings On Windows Debug builds, freeing inputfile in dinit_libraries() causes a _CrtIsValidHeapPointer assertion failure. The root cause was that the inputfile strings and the array are allocated in Rust using CString::into_raw() and Vec, which use Rust's global allocator. They were later freed in C using free(), causing a cross-allocator mismatch detected by the MSVC Debug CRT. The fix is to replace manual free() calls with free_rust_c_string_array() so that rust allocated memory is released using the correct allocator. --- src/lib_ccx/lib_ccx.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib_ccx/lib_ccx.c b/src/lib_ccx/lib_ccx.c index fb1b1b681..5f38f1a78 100644 --- a/src/lib_ccx/lib_ccx.c +++ b/src/lib_ccx/lib_ccx.c @@ -7,6 +7,7 @@ #include "ccx_decoders_isdb.h" struct ccx_common_logging_t ccx_common_logging; +extern void free_rust_c_string_array(char **arr, size_t count); static struct ccx_decoders_common_settings_t *init_decoder_setting( struct ccx_s_options *opt) { @@ -272,9 +273,11 @@ void dinit_libraries(struct lib_ccx_ctx **ctx) freep(&ccx_options.enc_cfg.output_filename); freep(&lctx->basefilename); freep(&lctx->pesheaderbuf); - for (i = 0; i < lctx->num_input_files; i++) - freep(&lctx->inputfile[i]); - freep(&lctx->inputfile); + if (lctx->inputfile) + { + free_rust_c_string_array(lctx->inputfile, lctx->num_input_files); + lctx->inputfile = NULL; + } freep(ctx); } From 6c7050465391f22ad1cfce880936ab7bf9b31db6 Mon Sep 17 00:00:00 2001 From: rhythmcache <153998419+rhythmcache@users.noreply.github.com> Date: Fri, 20 Feb 2026 09:57:55 +0530 Subject: [PATCH 2/2] Export free_rust_c_string_array with C ABI for FFI linkage --- src/rust/src/utils.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rust/src/utils.rs b/src/rust/src/utils.rs index b63838273..c2629c0d5 100644 --- a/src/rust/src/utils.rs +++ b/src/rust/src/utils.rs @@ -83,7 +83,8 @@ pub fn string_to_c_chars(strs: Vec) -> *mut *mut c_char { /// # Safety /// The pointers must have been allocated by `string_to_c_chars` or be null. /// `count` must be the number of strings in the array. -pub unsafe fn free_rust_c_string_array(arr: *mut *mut c_char, count: usize) { +#[no_mangle] +pub unsafe extern "C" fn free_rust_c_string_array(arr: *mut *mut c_char, count: usize) { if arr.is_null() { return; }