mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2026-04-05 21:51:23 +00:00
Fix integer overflow in ccxr_process_cc_data(): cast cc_count to usize before multiply (#2241)
cc_count * 3 used i32 arithmetic with no upper-bound check. For cc_count
> i32::MAX / 3 (~715 million), debug builds panic on overflow detection
and release builds silently wrap around to a negative range, discarding
all CC data for the frame. Both are triggerable from malformed media files.
Fix:
1. Cast cc_count to usize immediately after the existing <= 0 guard,
before any arithmetic — eliminates the overflow entirely
2. Add MAX_CC_COUNT = 31 upper-bound guard — CEA-708/ATSC A/53 encodes
cc_count in a 5-bit bitstream field (0x1F mask in avc_functions.c:514),
making 31 the spec-defined per-frame maximum; this value is also
independently documented in es/userdata.rs ("Maximum cc_count is 31").
Returns -1 with a warn!() log for out-of-range values, consistent with
existing error-handling style in the function.
3. Remove the now-redundant `x as usize` cast in the map closure since
the range is already usize..usize
Fixes #2234
This commit is contained in:
@@ -403,6 +403,19 @@ extern "C" fn ccxr_process_cc_data(
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Cast to usize before any arithmetic to prevent i32 overflow.
|
||||
// CEA-708/ATSC A/53 encodes cc_count in a 5-bit field (max 31); 31 is
|
||||
// also the value used in es/userdata.rs. Reject anything beyond that.
|
||||
const MAX_CC_COUNT: usize = 31;
|
||||
let cc_count_usize = cc_count as usize;
|
||||
if cc_count_usize > MAX_CC_COUNT {
|
||||
warn!(
|
||||
"ccxr_process_cc_data: cc_count {} exceeds maximum {}, discarding frame",
|
||||
cc_count_usize, MAX_CC_COUNT
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
|
||||
let dec_ctx = unsafe { &mut *dec_ctx };
|
||||
|
||||
// Check dtvcc_rust pointer before dereferencing (not dtvcc!)
|
||||
@@ -412,8 +425,8 @@ extern "C" fn ccxr_process_cc_data(
|
||||
}
|
||||
|
||||
let mut ret = -1;
|
||||
let mut cc_data: Vec<u8> = (0..cc_count * 3)
|
||||
.map(|x| unsafe { *data.add(x as usize) })
|
||||
let mut cc_data: Vec<u8> = (0..cc_count_usize * 3)
|
||||
.map(|x| unsafe { *data.add(x) })
|
||||
.collect();
|
||||
|
||||
// Use the persistent DtvccRust context from dtvcc_rust
|
||||
|
||||
Reference in New Issue
Block a user