[PR #1847] [MERGED] fix(hardsubx): Fix heap corruption from Rust/C allocator mismatch #2609

Closed
opened 2026-01-29 17:23:03 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/CCExtractor/ccextractor/pull/1847
Author: @cfsmp3
Created: 12/19/2025
Status: Merged
Merged: 12/19/2025
Merged by: @cfsmp3

Base: masterHead: ci/triage-failing-tests-dec-2025


📝 Commits (7)

  • 2fa023b ci: Add triage tracking file for December 2025 CI analysis
  • 0ef7227 ci: Add dummy C file to trigger Sample Platform CI
  • 0e815c6 fix(hardsubx): Fix crash in _dinit_hardsubx due to incorrect freep usage
  • 6399936 fix(hardsubx): Fix multiple memory bugs causing crashes
  • 80a117e fix(hardsubx): Fix memory leaks in hardsubx processing
  • 80957d6 fix(hardsubx): Fix heap corruption from Rust/C allocator mismatch
  • 0b74c92 fix(rcwt): Fix incorrect exit code when captions are found in BIN format

📊 Changes

8 files changed (+106 additions, -38 deletions)

View changed files

CI_TRIAGE_DEC_2025.md (+22 -0)
📝 src/lib_ccx/general_loop.c (+11 -0)
📝 src/lib_ccx/hardsubx.c (+7 -2)
📝 src/lib_ccx/hardsubx.h (+4 -0)
📝 src/lib_ccx/hardsubx_decoder.c (+18 -0)
📝 src/rust/src/hardsubx/classifier.rs (+27 -18)
📝 src/rust/src/hardsubx/decoder.rs (+15 -17)
📝 src/rust/src/utils.rs (+2 -1)

📄 Description

Summary

Fixes heap corruption in hardsubx (burned-in subtitle extraction) that caused garbage OCR output after processing ~27 subtitle frames.

Root Cause

The C code was using free() on strings allocated by Rust's CString::into_raw(). Since Rust and C use different memory allocators, this caused heap corruption that accumulated over time, eventually corrupting the OCR results.

Changes

  • src/rust/src/utils.rs: Export free_rust_c_string() as extern "C" function
  • src/lib_ccx/hardsubx.h: Declare free_rust_c_string() for C code
  • src/lib_ccx/hardsubx_decoder.c:
    • Replace free(subtitle_text) with free_rust_c_string(subtitle_text) for Rust-allocated strings
    • Fix memory leaks in process_hardsubx_linear_frames_and_normal_subs() where subtitle_text_hard and prev_subtitle_text_hard were not freed

Testing

Tool Result Details
AddressSanitizer PASS No memory errors detected
Valgrind Memcheck PASS 0 bytes definitely lost, 0 bytes indirectly lost
Manual testing PASS OCR output correct for entire video duration

Before/After

Before (memory corruption):

Frame 27: An unknown, a civilian. Kyle Reese.
Frame 28: y\na oo,
Frame 29: a\ni ft \\n* ur 2 + '

After (correct output):

Frame 27: Well, who's number one?
Frame 28: An unknown, a civilian. Kyle Reese.
Frame 29: [end of subtitles - no more dialogue]

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/CCExtractor/ccextractor/pull/1847 **Author:** [@cfsmp3](https://github.com/cfsmp3) **Created:** 12/19/2025 **Status:** ✅ Merged **Merged:** 12/19/2025 **Merged by:** [@cfsmp3](https://github.com/cfsmp3) **Base:** `master` ← **Head:** `ci/triage-failing-tests-dec-2025` --- ### 📝 Commits (7) - [`2fa023b`](https://github.com/CCExtractor/ccextractor/commit/2fa023b9fe58d2af4b39c2049ed1d368dc625ecb) ci: Add triage tracking file for December 2025 CI analysis - [`0ef7227`](https://github.com/CCExtractor/ccextractor/commit/0ef7227d7e1822ed5319358e268393671099372b) ci: Add dummy C file to trigger Sample Platform CI - [`0e815c6`](https://github.com/CCExtractor/ccextractor/commit/0e815c6e2dd2bd9d20fb98251135f7ad7edbbc5b) fix(hardsubx): Fix crash in _dinit_hardsubx due to incorrect freep usage - [`6399936`](https://github.com/CCExtractor/ccextractor/commit/63999369b7b8c52f130939b6def2adc533c29f89) fix(hardsubx): Fix multiple memory bugs causing crashes - [`80a117e`](https://github.com/CCExtractor/ccextractor/commit/80a117e64399557e86f05f848eeda75100aa8eaf) fix(hardsubx): Fix memory leaks in hardsubx processing - [`80957d6`](https://github.com/CCExtractor/ccextractor/commit/80957d645bf581721b4e151bd31f33774f4766d9) fix(hardsubx): Fix heap corruption from Rust/C allocator mismatch - [`0b74c92`](https://github.com/CCExtractor/ccextractor/commit/0b74c9226adc129b02c6b98898955bdaa224f368) fix(rcwt): Fix incorrect exit code when captions are found in BIN format ### 📊 Changes **8 files changed** (+106 additions, -38 deletions) <details> <summary>View changed files</summary> ➕ `CI_TRIAGE_DEC_2025.md` (+22 -0) 📝 `src/lib_ccx/general_loop.c` (+11 -0) 📝 `src/lib_ccx/hardsubx.c` (+7 -2) 📝 `src/lib_ccx/hardsubx.h` (+4 -0) 📝 `src/lib_ccx/hardsubx_decoder.c` (+18 -0) 📝 `src/rust/src/hardsubx/classifier.rs` (+27 -18) 📝 `src/rust/src/hardsubx/decoder.rs` (+15 -17) 📝 `src/rust/src/utils.rs` (+2 -1) </details> ### 📄 Description ## Summary Fixes heap corruption in hardsubx (burned-in subtitle extraction) that caused garbage OCR output after processing ~27 subtitle frames. ### Root Cause The C code was using `free()` on strings allocated by Rust's `CString::into_raw()`. Since Rust and C use different memory allocators, this caused heap corruption that accumulated over time, eventually corrupting the OCR results. ### Changes - **src/rust/src/utils.rs**: Export `free_rust_c_string()` as `extern "C"` function - **src/lib_ccx/hardsubx.h**: Declare `free_rust_c_string()` for C code - **src/lib_ccx/hardsubx_decoder.c**: - Replace `free(subtitle_text)` with `free_rust_c_string(subtitle_text)` for Rust-allocated strings - Fix memory leaks in `process_hardsubx_linear_frames_and_normal_subs()` where `subtitle_text_hard` and `prev_subtitle_text_hard` were not freed ### Testing | Tool | Result | Details | |------|--------|---------| | AddressSanitizer | ✅ PASS | No memory errors detected | | Valgrind Memcheck | ✅ PASS | 0 bytes definitely lost, 0 bytes indirectly lost | | Manual testing | ✅ PASS | OCR output correct for entire video duration | ### Before/After **Before (memory corruption):** ``` Frame 27: An unknown, a civilian. Kyle Reese. Frame 28: y\na oo, Frame 29: a\ni ft \\n* ur 2 + ' ``` **After (correct output):** ``` Frame 27: Well, who's number one? Frame 28: An unknown, a civilian. Kyle Reese. Frame 29: [end of subtitles - no more dialogue] ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-29 17:23:03 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/ccextractor#2609