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 1 commit intoCCExtractor:masterfrom
Conversation
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 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 |
|
With which sample can I validate this? |
|
Hi @cfsmp3! The fix can be validated with any DVB Transport Stream The easiest way to reproduce the issue and validate the fix:
The CI bot results already confirm this — 9 tests that have If you need a specific sample file I can help identify the best |
CCExtractor CI platform finished running the test files on linux. Below is a summary of the test results, when compared to test for commit 90128d8...:
Your PR breaks these cases:
NOTE: The following tests have been failing on the master branch as well as the PR:
Congratulations: Merging this PR would fix the following tests:
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. |
|
@Varadraj75 give me exact repro steps please, I downloaded sample 21 and I can't see the difference - so tell me what to run before and after applying your PR. |
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.
e0b29eb to
c5bf924
Compare
c5bf924 to
15b8f71
Compare
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