From 90c439d9c725e341b1c9637a3001b3e564832270 Mon Sep 17 00:00:00 2001 From: Dhanush Varma Date: Mon, 16 Mar 2026 20:05:45 +0530 Subject: [PATCH] fix: MKV demuxer crash due to NULL file path Root cause: detect_stream_type() calls buffered_read_opt() which triggers switch_to_next_file() on EOF, incrementing current_file past the valid range. matroska_loop then accesses ctx->inputfile[current_file] and gets NULL. Fix: save and restore current_file around detect_stream_type() in both the C (ccx_demuxer.c) and Rust (demux.rs) open functions. This preserves correct behavior for multi-file input where current_file is legitimately > 0. --- src/lib_ccx/ccx_demuxer.c | 4 ++++ src/lib_ccx/matroska.c | 1 + src/rust/src/demuxer/demux.rs | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/src/lib_ccx/ccx_demuxer.c b/src/lib_ccx/ccx_demuxer.c index f87e99584..269698f87 100644 --- a/src/lib_ccx/ccx_demuxer.c +++ b/src/lib_ccx/ccx_demuxer.c @@ -134,9 +134,13 @@ static int ccx_demuxer_open(struct ccx_demuxer *ctx, const char *file) return -1; } + struct lib_ccx_ctx *parent_ctx = (struct lib_ccx_ctx *)ctx->parent; + int saved_current_file = parent_ctx ? parent_ctx->current_file : -1; if (ctx->auto_stream == CCX_SM_AUTODETECT) { detect_stream_type(ctx); + if (parent_ctx) + parent_ctx->current_file = saved_current_file; switch (ctx->stream_mode) { case CCX_SM_ELEMENTARY_OR_NOT_FOUND: diff --git a/src/lib_ccx/matroska.c b/src/lib_ccx/matroska.c index 3b3d8a815..086f9c7b7 100644 --- a/src/lib_ccx/matroska.c +++ b/src/lib_ccx/matroska.c @@ -2005,6 +2005,7 @@ void matroska_parse(struct matroska_ctx *mkv_ctx) FILE *create_file(struct lib_ccx_ctx *ctx) { + char *filename = ctx->inputfile[ctx->current_file]; FILE *file = fopen(filename, "rb"); return file; diff --git a/src/rust/src/demuxer/demux.rs b/src/rust/src/demuxer/demux.rs index fec29b319..3eedef056 100755 --- a/src/rust/src/demuxer/demux.rs +++ b/src/rust/src/demuxer/demux.rs @@ -247,8 +247,12 @@ impl CcxDemuxer<'_> { } } // Stream mode detection + let saved_current_file = self.parent.as_ref().map(|p| p.current_file); if self.auto_stream == StreamMode::Autodetect { detect_stream_type(self, ccx_options); + if let (Some(parent), Some(saved)) = (self.parent.as_mut(), saved_current_file) { + parent.current_file = saved; + } match self.stream_mode { StreamMode::ElementaryOrNotFound => { info!("\rFile seems to be an elementary stream")