Skip to content

Commit e663eca

Browse files
authored
fix: XDS segmentation faults (#1707)
* fix: XDS segmentation faults * fix: memory leaks in unit tests for service decoder
1 parent 77b93e5 commit e663eca

File tree

2 files changed

+60
-39
lines changed

2 files changed

+60
-39
lines changed

docs/CHANGES.TXT

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
1.0 (to be released)
22
-----------------
3+
- Fix: Segmentation faults on XDS files
34
- Fix: Clippy Errors Based on Rust 1.88
45
- IMPROVEMENT: Refactor and optimize Dockerfile
56
- Fix: Improved handling of IETF language tags in Matroska files (#1665)

src/rust/src/decoder/service_decoder.rs

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,15 @@ impl dtvcc_service_decoder {
11361136
window.is_empty = 0;
11371137

11381138
// Add symbol to window
1139-
window.rows[window.pen_row as usize] = Box::into_raw(Box::new(sym));
1139+
if window.memory_reserved == 1 {
1140+
unsafe {
1141+
let ptr: *mut dtvcc_symbol =
1142+
window.rows[window.pen_row as usize].add(window.pen_column as usize);
1143+
*ptr = sym;
1144+
}
1145+
} else {
1146+
return;
1147+
}
11401148

11411149
// "Painting" char by pen - attribs
11421150
window.pen_attribs[window.pen_row as usize][window.pen_column as usize] =
@@ -1225,6 +1233,30 @@ mod test {
12251233
use super::*;
12261234
use crate::utils::get_zero_allocated_obj;
12271235

1236+
fn setup_test_decoder_with_memory() -> dtvcc_service_decoder {
1237+
let mut decoder = get_zero_allocated_obj::<dtvcc_service_decoder>();
1238+
1239+
decoder.current_window = 0;
1240+
decoder.windows[0].is_defined = 1;
1241+
decoder.windows[0].row_count = 4;
1242+
decoder.windows[0].col_count = 4;
1243+
decoder.windows[0].attribs.print_direction =
1244+
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT as i32;
1245+
1246+
let layout = Layout::array::<dtvcc_symbol>(CCX_DTVCC_MAX_COLUMNS as usize).unwrap();
1247+
decoder.windows[0].rows[0] = unsafe { alloc(layout) } as *mut dtvcc_symbol;
1248+
decoder.windows[0].memory_reserved = 1;
1249+
1250+
*decoder
1251+
}
1252+
1253+
fn cleanup_test_decoder(decoder: &mut dtvcc_service_decoder) {
1254+
let layout = Layout::array::<dtvcc_symbol>(CCX_DTVCC_MAX_COLUMNS as usize).unwrap();
1255+
unsafe {
1256+
dealloc(decoder.windows[0].rows[0] as *mut u8, layout);
1257+
}
1258+
}
1259+
12281260
// -------------------------- C0 Commands-------------------------
12291261
#[test]
12301262
fn test_process_cr() {
@@ -1378,13 +1410,7 @@ mod test {
13781410

13791411
#[test]
13801412
fn test_process_p16() {
1381-
let mut decoder = get_zero_allocated_obj::<dtvcc_service_decoder>();
1382-
decoder.current_window = 0;
1383-
decoder.windows[0].is_defined = 1;
1384-
decoder.windows[0].row_count = 4;
1385-
decoder.windows[0].col_count = 4;
1386-
decoder.windows[0].attribs.print_direction =
1387-
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT as i32;
1413+
let mut decoder = setup_test_decoder_with_memory();
13881414
let block = [b'a', b'b'] as [c_uchar; 2];
13891415

13901416
decoder.process_p16(&block);
@@ -1393,10 +1419,12 @@ mod test {
13931419
assert_eq!(decoder.windows[0].pen_column, 1);
13941420
unsafe {
13951421
assert_eq!(
1396-
*decoder.windows[0].rows[0],
1422+
*decoder.windows[0].rows[0].add(0),
13971423
dtvcc_symbol::new_16(block[0], block[1])
13981424
);
13991425
}
1426+
1427+
cleanup_test_decoder(&mut decoder);
14001428
}
14011429

14021430
// -------------------------- C1 Commands-------------------------
@@ -1640,14 +1668,7 @@ mod test {
16401668
// -------------------------- G0, G1 and extended Commands-------------------------
16411669
#[test]
16421670
fn test_handle_G0() {
1643-
let mut decoder = get_zero_allocated_obj::<dtvcc_service_decoder>();
1644-
1645-
decoder.current_window = 0;
1646-
decoder.windows[0].is_defined = 1;
1647-
decoder.windows[0].row_count = 4;
1648-
decoder.windows[0].col_count = 4;
1649-
decoder.windows[0].attribs.print_direction =
1650-
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT as i32;
1671+
let mut decoder = setup_test_decoder_with_memory();
16511672

16521673
// Case: block[0] == 0x7F
16531674
let block = [0x7F, 0x61];
@@ -1657,7 +1678,7 @@ mod test {
16571678
assert_eq!(decoder.windows[0].pen_column, 1);
16581679
unsafe {
16591680
assert_eq!(
1660-
decoder.windows[0].rows[0].read().sym,
1681+
decoder.windows[0].rows[0].add(0).read().sym,
16611682
CCX_DTVCC_MUSICAL_NOTE_CHAR
16621683
);
16631684
}
@@ -1668,20 +1689,15 @@ mod test {
16681689

16691690
assert_eq!(return_value, 1);
16701691
unsafe {
1671-
assert_eq!(decoder.windows[0].rows[0].read().sym, 96);
1692+
assert_eq!(decoder.windows[0].rows[0].add(1).read().sym, 96);
16721693
}
1694+
1695+
cleanup_test_decoder(&mut decoder);
16731696
}
16741697

16751698
#[test]
16761699
fn test_handle_G1() {
1677-
let mut decoder = get_zero_allocated_obj::<dtvcc_service_decoder>();
1678-
1679-
decoder.current_window = 0;
1680-
decoder.windows[0].is_defined = 1;
1681-
decoder.windows[0].row_count = 4;
1682-
decoder.windows[0].col_count = 4;
1683-
decoder.windows[0].attribs.print_direction =
1684-
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT as i32;
1700+
let mut decoder = setup_test_decoder_with_memory();
16851701

16861702
let block = [0x7F, 0x61];
16871703
let return_value = decoder.handle_G1(&block);
@@ -1690,20 +1706,15 @@ mod test {
16901706
assert_eq!(decoder.windows[0].pen_row, 0);
16911707
assert_eq!(decoder.windows[0].pen_column, 1);
16921708
unsafe {
1693-
assert_eq!(decoder.windows[0].rows[0].read().sym, 0x7F);
1709+
assert_eq!(decoder.windows[0].rows[0].add(0).read().sym, 0x7F);
16941710
}
1711+
1712+
cleanup_test_decoder(&mut decoder);
16951713
}
16961714

16971715
#[test]
16981716
fn test_handle_extended_char() {
1699-
let mut decoder = get_zero_allocated_obj::<dtvcc_service_decoder>();
1700-
1701-
decoder.current_window = 0;
1702-
decoder.windows[0].is_defined = 1;
1703-
decoder.windows[0].row_count = 4;
1704-
decoder.windows[0].col_count = 4;
1705-
decoder.windows[0].attribs.print_direction =
1706-
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT as i32;
1717+
let mut decoder = setup_test_decoder_with_memory();
17071718

17081719
// 0..=0x1F
17091720
let return_value = decoder.handle_extended_char(&[0x1A, 0x61]);
@@ -1715,7 +1726,7 @@ mod test {
17151726
assert_eq!(decoder.windows[0].pen_row, 0);
17161727
assert_eq!(decoder.windows[0].pen_column, 1);
17171728
unsafe {
1718-
assert_eq!(decoder.windows[0].rows[0].read().sym, 0x5);
1729+
assert_eq!(decoder.windows[0].rows[0].add(0).read().sym, 0x5);
17191730
}
17201731

17211732
// 0x80..=0x9F
@@ -1728,8 +1739,10 @@ mod test {
17281739
assert_eq!(decoder.windows[0].pen_row, 0);
17291740
assert_eq!(decoder.windows[0].pen_column, 2);
17301741
unsafe {
1731-
assert_eq!(decoder.windows[0].rows[0].read().sym, 0x20);
1742+
assert_eq!(decoder.windows[0].rows[0].add(1).read().sym, 0x20);
17321743
}
1744+
1745+
cleanup_test_decoder(&mut decoder);
17331746
}
17341747

17351748
#[test]
@@ -1754,13 +1767,20 @@ mod test {
17541767
decoder.windows[0].attribs.print_direction =
17551768
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT as i32;
17561769

1770+
let layout = Layout::array::<dtvcc_symbol>(CCX_DTVCC_MAX_COLUMNS as usize).unwrap();
1771+
decoder.windows[0].rows[0] = unsafe { alloc(layout) } as *mut dtvcc_symbol;
1772+
decoder.windows[0].memory_reserved = 1;
1773+
17571774
decoder.process_character(sym);
17581775

17591776
// Check changes
17601777
assert_eq!(decoder.windows[0].pen_row, 0);
17611778
assert_eq!(decoder.windows[0].pen_column, 1);
17621779
unsafe {
1763-
assert_eq!(decoder.windows[0].rows[0].read(), dtvcc_symbol::new(0x41));
1780+
assert_eq!(
1781+
decoder.windows[0].rows[0].add(0).read(),
1782+
dtvcc_symbol::new(0x41)
1783+
);
17641784
}
17651785
}
17661786
}

0 commit comments

Comments
 (0)