mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2026-04-05 21:51:23 +00:00
Fix heap OOB read in switch_to_next_file(): sync inputfile array with num_input_files (#2218)
The Rust FFI function copy_from_rust() computed num_input_files by filtering empty strings from the inputfiles Vec, but passed an unfiltered clone to string_to_c_chars() to build the C inputfile[] array. This mismatch made the C array length and num_input_files disagree: switch_to_next_file() could index inputfile[current_file] where current_file < num_input_files but >= array size, reading one slot past the end of the allocated array — confirmed by AddressSanitizer (heap-buffer-overflow at file_functions.c:183). The same count/size mismatch also caused free_rust_c_string_array() to reconstruct the Vec with an incorrect capacity, producing heap corruption on every clean shutdown. Fix: filter empty strings into a single Vec<String> first, then derive both num_input_files (filtered.len()) and the C array (string_to_c_chars(filtered)) from that same source, eliminating the mismatch entirely. Fixes #2182 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -257,9 +257,18 @@ pub unsafe fn copy_from_rust(ccx_s_options: *mut ccx_s_options, options: Options
|
||||
// Freeing them would cause use-after-free and double-free errors.
|
||||
if let Some(ref inputfile) = options.inputfile {
|
||||
if (*ccx_s_options).inputfile.is_null() {
|
||||
(*ccx_s_options).inputfile = string_to_c_chars(inputfile.clone());
|
||||
(*ccx_s_options).num_input_files =
|
||||
inputfile.iter().filter(|s| !s.is_empty()).count() as _;
|
||||
// Filter empty strings into a single Vec so that the C array length
|
||||
// and num_input_files are always derived from the same source.
|
||||
// Previously string_to_c_chars received the full (unfiltered) Vec
|
||||
// while num_input_files was the filtered count, causing a mismatch
|
||||
// that let switch_to_next_file() read past the end of the array.
|
||||
let filtered: Vec<String> = inputfile
|
||||
.iter()
|
||||
.filter(|s| !s.is_empty())
|
||||
.cloned()
|
||||
.collect();
|
||||
(*ccx_s_options).num_input_files = filtered.len() as _;
|
||||
(*ccx_s_options).inputfile = string_to_c_chars(filtered);
|
||||
}
|
||||
}
|
||||
(*ccx_s_options).demux_cfg = options.demux_cfg.to_ctype();
|
||||
|
||||
Reference in New Issue
Block a user