FIX: Flush pending EIT sections in EPG_free() before freeing buffers#2166
FIX: Flush pending EIT sections in EPG_free() before freeing buffers#2166Varadraj75 wants to merge 3 commits intoCCExtractor:masterfrom
Conversation
parse_EPG_packet() accumulates TS continuation packets into epg_buffers[] and only calls EPG_parse_table() when a new section starts (payload_start_indicator=1). This meant the last EIT section in any stream was never parsed — there is no following packet to trigger the flush. EPG_free() now iterates over all epg_buffers slots and flushes any with ccounter > 0 before freeing, ensuring the last section is always processed. Fixes #ISSUE_NUMBER
parse_EPG_packet() accumulates TS continuation packets into epg_buffers[] and only calls EPG_parse_table() when a new section starts (payload_start_indicator=1). This meant the last EIT section in any stream was never parsed — there is no following packet to trigger the flush. EPG_free() now iterates over all epg_buffers slots and flushes any with ccounter > 0 before freeing, ensuring the last section is always processed. Fixes CCExtractor#2165
There was a problem hiding this comment.
Pull request overview
This PR fixes a long-standing Transport Stream EPG edge case where the final accumulated EIT/PSI section was never parsed because parsing was only triggered when a new section started, causing the last section in the stream to be silently dropped.
Changes:
- Flush any pending EIT sections from
epg_buffers[]duringEPG_free()before freeing EPG state. - Document the fix in the changelog (references #2165).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/lib_ccx/ts_tables_epg.c |
Flushes buffered (previously unflushed) EIT sections during cleanup to avoid losing the final section. |
docs/CHANGES.TXT |
Adds a changelog entry describing the fix and linking to the reported issue. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/lib_ccx/ts_tables_epg.c
Outdated
| { | ||
| if (ctx->epg_buffers[i].buffer != NULL && ctx->epg_buffers[i].ccounter > 0) | ||
| { | ||
| EPG_parse_table(ctx, ctx->epg_buffers[i].buffer, ctx->epg_buffers[i].buffer_length); |
There was a problem hiding this comment.
Before calling EPG_parse_table() here, please validate that the pending buffer is large enough (e.g., buffer_length > 0 and pointer_field+1 < buffer_length) to avoid out-of-bounds reads when the last buffered section is truncated/malformed or when payload_length ended up as 0. This flush path can now parse buffers that previously would have been dropped at shutdown, so it should be resilient to incomplete data.
| EPG_parse_table(ctx, ctx->epg_buffers[i].buffer, ctx->epg_buffers[i].buffer_length); | |
| // Validate buffer before parsing to avoid out-of-bounds reads | |
| if (ctx->epg_buffers[i].buffer_length > 0) | |
| { | |
| unsigned char pointer_field = (unsigned char)ctx->epg_buffers[i].buffer[0]; | |
| if ((size_t)pointer_field + 1 < (size_t)ctx->epg_buffers[i].buffer_length) | |
| { | |
| EPG_parse_table(ctx, | |
| ctx->epg_buffers[i].buffer, | |
| ctx->epg_buffers[i].buffer_length); | |
| } | |
| } |
Validate buffer_length > 0 and pointer_field+1 < buffer_length before calling EPG_parse_table() to avoid out-of-bounds reads on truncated or malformed EIT sections at stream end. Addresses Copilot review comment on CCExtractor#2166.
CCExtractor CI platform finished running the test files on linux. Below is a summary of the test results, when compared to test for commit f377be9...:
Congratulations: Merging this PR would fix the following tests:
All tests passed completely. Check the result page for more info. |
CCExtractor CI platform finished running the test files on windows. Below is a summary of the test results, when compared to test for commit f377be9...:
Your PR breaks these cases:
It seems that not all tests were passed completely. This is an indication that the output of some files is not as expected (but might be according to you). Check the result page for more info. |
|
The Windows CI failures are pre-existing and unrelated to this change:
This PR only modifies |
In raising this pull request, I confirm the following (please check boxes):
My familiarity with the project is as follows (check one):
Summary
Fixes #2165 — the last EIT section in any stream was silently discarded.
Root Cause
parse_EPG_packet()accumulates TS packets intoepg_buffers[]and onlycalls
EPG_parse_table()when a new section starts (payload_start_indicator=1).This means the last accumulated section is never parsed — there is no
following packet to trigger the flush.
EPG_free()then freed the buffers without processing them, silentlydiscarding the last EIT section in every stream.
Fix
EPG_free()now iterates over allepg_buffersslots before freeing andflushes any with
ccounter > 0:Impact
where the last section represents a significant portion of the EPG data
Testing
Built and verified locally on macOS. All existing CI tests pass.
Fixes #2165