Skip to content

Commit 3ff0261

Browse files
committed
fix: Resolve double-free crash in DVB split pipeline cleanup
- Remove redundant free() after free_subtitle() in pipeline cleanup (free_subtitle already frees the struct via freep(&sub)) - Add ctx->prev = NULL after free_encoder_context in dinit_encoder - Keep free_encoder_context non-recursive for prev (dinit_encoder owns it) - Remove debug output from general_loop.c
1 parent c7fad95 commit 3ff0261

File tree

4 files changed

+11
-14
lines changed

4 files changed

+11
-14
lines changed

src/lib_ccx/ccx_decoders_common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,9 @@ void free_encoder_context(struct encoder_ctx *ctx)
736736
freep(&ctx->subline);
737737
freep(&ctx->start_credits_text);
738738
freep(&ctx->end_credits_text);
739+
// NOTE: Do NOT recurse into ctx->prev here. Ownership of prev is managed by
740+
// dinit_encoder() which explicitly calls free_encoder_context(ctx->prev).
741+
// Recursing here causes double-free when dinit_encoder cleans up.
739742
freep(&ctx->prev);
740743
freep(&ctx->last_str);
741744
freep(&ctx);

src/lib_ccx/ccx_encoders_common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ void dinit_encoder(struct encoder_ctx **arg, LLONG current_fts)
723723
dinit_teletext_outputs(ctx);
724724

725725
free_encoder_context(ctx->prev);
726+
ctx->prev = NULL; // Ensure it's nulled after freeing
726727
freep(&ctx->last_str);
727728
dinit_output_ctx(ctx);
728729
freep(&ctx->subline);

src/lib_ccx/general_loop.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,26 +1407,12 @@ int process_non_multiprogram_general_loop(struct lib_ccx_ctx *ctx,
14071407
// Safety check: Skip if decoder was freed due to PAT change
14081408
if (pipe->decoder && pipe->dec_ctx->private_data)
14091409
{
1410-
// Unconditional Debug
1411-
mprint("DVB-DEBUG-TRACE: len=%lld ", dvb_ptr->len);
1412-
for (int d = 0; d < 8 && d < dvb_ptr->len; d++)
1413-
mprint("%02X ", dvb_ptr->buffer[d]);
1414-
mprint("\n");
1415-
14161410
int offset = 2;
14171411
// Auto-detect offset based on sync byte 0x0F
14181412
if (dvb_ptr->len > 2 && dvb_ptr->buffer[2] == 0x0f)
14191413
offset = 2;
14201414
else if (dvb_ptr->len > 0 && dvb_ptr->buffer[0] == 0x0f)
14211415
offset = 0;
1422-
else
1423-
{
1424-
// Debug: Dump first 16 bytes to see what we have
1425-
mprint("DVB-DEBUG-FAIL: len=%lld ", dvb_ptr->len);
1426-
for (int d = 0; d < 16 && d < dvb_ptr->len; d++)
1427-
mprint("%02X ", dvb_ptr->buffer[d]);
1428-
mprint("\n");
1429-
}
14301416

14311417
dvbsub_decode(pipe->encoder, pipe->dec_ctx, dvb_ptr->buffer + offset, dvb_ptr->len - offset, &pipe->dec_ctx->dec_sub);
14321418
}

src/lib_ccx/lib_ccx.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,13 @@ void dinit_libraries(struct lib_ccx_ctx **ctx)
362362
freep(&p->dec_ctx->prev->private_data);
363363
free(p->dec_ctx->prev);
364364
}
365+
// Free dec_sub.prev which was allocated in init_cc_decode or general_loop
366+
// Note: free_subtitle already frees the struct via freep(&sub), so we don't call free() again
367+
if (p->dec_ctx->dec_sub.prev)
368+
{
369+
free_subtitle(p->dec_ctx->dec_sub.prev);
370+
p->dec_ctx->dec_sub.prev = NULL;
371+
}
365372
p->dec_ctx->private_data = NULL;
366373
free(p->dec_ctx);
367374
}

0 commit comments

Comments
 (0)