Skip to content

[FIX] rcwt_loop: decide teletext mode once from the file header - #2430

Open
VishnuSrivatsava wants to merge 1 commit into
CCExtractor:masterfrom
VishnuSrivatsava:fix/rcwt-teletext-branch-null
Open

VishnuSrivatsava wants to merge 1 commit into
CCExtractor:masterfrom
VishnuSrivatsava:fix/rcwt-teletext-branch-null

Conversation

@VishnuSrivatsava

Copy link
Copy Markdown

In raising this pull request, I confirm the following (please check boxes):

Reason for this PR:

  • This PR adds new functionality.
  • This PR fixes a bug that I have personally experienced or that a real user has reported and for which a sample exists.
  • This PR is porting code from C to Rust.

Sanity check:

  • I have read and understood the contributors guide.
  • I have checked that another pull request for this purpose does not exist.
  • If the PR adds new functionality, I've added it to the changelog. If it's just a bug fix, I have NOT added it to the changelog.
  • I am NOT adding new C code unless it's to fix an existing, reproducible bug.

Fixes #2429

Repro instructions:

Sample (83 bytes): https://gist.github.com/VishnuSrivatsava/79a2d40af506ebabbfe925de9305fb08
(gh does not accept binary gists, so it is base64-encoded: base64 -d crash.rcwt.b64 > crash.rcwt,
SHA256 6565e25b9b773ee1ad2731eb3b07ed7266d8f7dfbf2e3601084cc6347ab8c701.)

  • ccextractor crash.rcwt on master d7eb132e: exit 139 (SIGSEGV).
  • With an AddressSanitizer build:
    SEGV ... WRITE of size 8 ... #0 tlt_read_rcwt telxcc.c:1327 / #1 rcwt_loop general_loop.c:1801.

Details and evidence in #2429.


Why it happens

In rcwt_loop() the teletext-vs-608 choice is made by testing parsebuf[6] == 0 && parsebuf[7] == 2
(the file header's format-revision bytes) both before the loop and at the top of every loop
iteration. In 608 mode parsebuf is reused for the 10-byte data header and then realloc'd and
overwritten with the raw caption-block bytes, so iteration 2+ inspects caption bytes, not the
header. When the CC byte stream contains 00 02 at offsets 6–7, the file is routed to
tlt_read_rcwt() although the teletext context was never initialized (telxcc_init() only runs
in teletext mode) → memcpy(&(NULL->last_timestamp), ...) → SIGSEGV.

The fix

Decide the mode once from the file header, into int is_teletext, and test the flag in the loop.
+7/−2, one file.

Verification performed

  • PoC: SIGSEGV on master → exits cleanly with the patch.
  • A control input with caption bytes 00 03 (instead of 00 02) does not crash on master,
    and a genuine teletext-mode RCWT (header revision 00 02) does not crash either —
    confirming the branch-selection is the specific cause.
  • Teletext-mode RCWT: console output byte-identical before/after the patch.
  • Regression: real TS samples (La_Chevre_PATPMTevery6s.ts, EIT_bogus_encoding.ts,
    a HEVC sample) produce identical output/exit codes on both builds.
  • clang-format -i produces no changes; no Rust code touched.

Limitations

  • I could not test against a real teletext RCWT recording; the teletext path was exercised via
    the format as written by writercwtdata()/tlt_read_rcwt() semantics. The flag is set from the
    same header bytes the old pre-loop check used, so the teletext decision itself is unchanged.

The loop re-read parsebuf[6..7] every iteration to choose between the
teletext and CEA-608 paths, but in 608 mode parsebuf is reused for data
headers and caption blocks, so raw caption bytes 00 02 at offsets 6-7
routed the stream into tlt_read_rcwt() with a NULL teletext context
(SEGV in telxcc.c, memcpy to NULL->last_timestamp).

Capture the decision in a flag right after the 11-byte file header is
validated, and use it inside the loop.
@VishnuSrivatsava

Copy link
Copy Markdown
Author

The Linux build jobs failing here are pre-existing runner breakage, not caused by this patch. Every "Build CCExtractor on Linux" job dies in the Install dependencies step with E: Package 'libgpac-dev' has no installation candidate (exit 100), which is the situation tracked in #2254: the ubuntu-latest image no longer ships libgpac-dev. The same failures appear on other recent PRs; older PRs' green checks predate the runner image change (for example #2424's passed on Oct 21).

The format job failure is also unrelated to this change: its diff touches only src/lib_ccx/ccx_decoders_isdb.c and src/lib_ccx/mp4.c, files this PR does not modify. The runner's clang-format version now disagrees with those files as they exist on master. src/lib_ccx/general_loop.c, the only file this PR changes, does not appear in the format diff, and the standalone build_rust job passes on this branch.

Leaving the CI situation to the maintainers. The patch itself is a 7-line change in general_loop.c verified locally on macOS: the PoC from #2429 exits cleanly, teletext-mode RCWT output is unchanged, and a 12-sample corpus shows identical results. If it's useful, I'm happy to help with the #2254 CI side (for example building gpac from source in the workflows) as a separate change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] SIGSEGV in tlt_read_rcwt(): rcwt_loop re-checks parsebuf[6..7] after it was overwritten with caption data (608-mode RCWT)

1 participant