Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/lib_ccx/ccx_encoders_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,13 @@ static int init_output_ctx(struct encoder_ctx *ctx, struct encoder_cfg *cfg)

if (cfg->cc_to_stdout)
{
#ifdef WIN32
ctx->dtvcc_writers[i].fd = -1;
ctx->dtvcc_writers[i].fhandle = GetStdHandle(STD_OUTPUT_HANDLE);
#else
ctx->dtvcc_writers[i].fd = STDOUT_FILENO;
ctx->dtvcc_writers[i].fhandle = NULL;
#endif
ctx->dtvcc_writers[i].charset = NULL;
ctx->dtvcc_writers[i].filename = NULL;
ctx->dtvcc_writers[i].cd = (iconv_t)-1;
Expand Down
1 change: 0 additions & 1 deletion src/rust/src/decoder/service_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1118,7 +1118,6 @@ impl dtvcc_service_decoder {

/// Process the character and add it to the current window
pub fn process_character(&mut self, sym: dtvcc_symbol) {
debug!("{}", self.current_window);
let window = &mut self.windows[self.current_window as usize];
let window_state = if is_true(window.is_defined) {
"OK"
Expand Down
73 changes: 73 additions & 0 deletions src/rust/src/decoder/tv_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,4 +735,77 @@ mod test {
assert!(!screen.is_row_empty(0));
assert!(screen.is_row_empty(1));
}

#[test]
#[cfg(unix)]
fn test_writer_output_with_valid_fd() {
// Test that writer_output works when fd is already set (stdout mode)
// This tests the fix for issue #1693
use std::fs::File;
use std::os::unix::io::{FromRawFd, IntoRawFd};
use tempfile::tempfile;

let screen = get_zero_allocated_obj::<dtvcc_tv_screen>();
let mut writer_ctx = get_zero_allocated_obj::<dtvcc_writer_ctx>();
let transcript_settings = get_zero_allocated_obj::<ccx_encoders_transcript_format>();

// Create a temp file and use its fd (simulates stdout being pre-set)
let temp_file = tempfile().expect("Failed to create temp file");
writer_ctx.fd = temp_file.into_raw_fd();
writer_ctx.filename = std::ptr::null_mut(); // filename is null in stdout mode

let mut counter = 0u32;
let mut writer = Writer::new(
&mut counter,
0,
ccx_output_format::CCX_OF_SRT,
&mut writer_ctx,
0,
&transcript_settings,
0,
);

// This should succeed without error (fd is valid, not -1)
let result = screen.writer_output(&mut writer);
assert!(
result.is_ok(),
"writer_output should succeed when fd is valid"
);

// Clean up: convert fd back to File so it gets closed on drop
let _file = unsafe { File::from_raw_fd(writer_ctx.fd) };
}

#[test]
#[cfg(unix)]
fn test_writer_output_missing_filename_and_fd() {
// Test that writer_output returns error when both filename and fd are invalid
// This is the expected behavior that was causing panic before the fix
let screen = get_zero_allocated_obj::<dtvcc_tv_screen>();
let mut writer_ctx = get_zero_allocated_obj::<dtvcc_writer_ctx>();
let transcript_settings = get_zero_allocated_obj::<ccx_encoders_transcript_format>();

// Both filename is null and fd is -1 (invalid state)
writer_ctx.fd = -1;
writer_ctx.filename = std::ptr::null_mut();

let mut counter = 0u32;
let mut writer = Writer::new(
&mut counter,
0,
ccx_output_format::CCX_OF_SRT,
&mut writer_ctx,
0,
&transcript_settings,
0,
);

// This should return an error, not panic
let result = screen.writer_output(&mut writer);
assert!(
result.is_err(),
"writer_output should return error when filename and fd are invalid"
);
assert_eq!(result.unwrap_err(), "Filename missing");
}
}
5 changes: 3 additions & 2 deletions src/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ extern "C" {
pub fn ccx_gxf_init(arg: *mut ccx_demuxer) -> *mut ccx_gxf;
}

/// Initialize env logger with custom format, using stdout as target
/// Initialize env logger with custom format, using stderr as target
/// This ensures debug output doesn't pollute stdout when using --stdout option
///
/// # Safety
///
Expand All @@ -204,7 +205,7 @@ pub extern "C" fn ccxr_init_logger() {
builder()
.format(|buf, record| writeln!(buf, "[CEA-708] {}", record.args()))
.filter_level(LevelFilter::Debug)
.target(Target::Stdout)
.target(Target::Stderr)
.init();
}

Expand Down
Loading