From 4b02ff28456de24d112d1d41acedb351a1ad4ffb Mon Sep 17 00:00:00 2001 From: Griffin Long <151978260+DrunkOnJava@users.noreply.github.com> Date: Wed, 28 Oct 2026 06:53:08 -0400 Subject: [PATCH] test(tables): delete the symbol-table decoders' inline mirror suites The inline #[cfg(test)] modules of tables/appid, ltype, style and mod build synthetic bit streams in each decoder's own field layout and assert the fields they decode. They are unit tests, which this repository bans, and no job runs them since the Test job moved to tools/ci/run_test_targets.sh. Git history is the archive. The six table files an open pull request touches keep theirs until those land. --- src/tables/appid.rs | 41 ----------- src/tables/ltype.rs | 171 -------------------------------------------- src/tables/mod.rs | 27 ------- src/tables/style.rs | 136 ----------------------------------- 4 files changed, 375 deletions(-) diff --git a/src/tables/appid.rs b/src/tables/appid.rs index 0413c532..1835368a 100644 --- a/src/tables/appid.rs +++ b/src/tables/appid.rs @@ -58,44 +58,3 @@ pub(crate) fn decode_modern_split_stream( unknown, }) } - -#[cfg(test)] -mod tests { - use super::*; - use crate::bitwriter::BitWriter; - - #[test] - fn roundtrip_acad_appid() { - let mut w = BitWriter::new(); - let s = b"ACAD"; - w.write_bs_u(s.len() as u16); - for b in s { - w.write_rc(*b); - } - w.write_b(false); - w.write_bs(0); - w.write_b(false); - w.write_rc(0x00); - let bytes = w.into_bytes(); - let mut c = BitCursor::new(&bytes); - let a = decode(&mut c, Version::R2000).unwrap(); - assert_eq!(a.header.name, "ACAD"); - } - - #[test] - fn r2007_split_stream_appid_reads_name_from_string_stream() { - let mut body = BitWriter::new(); - body.write_bs_u(0); // no EED - body.write_bl(0); // no reactors - body.write_b(true); // no xdictionary - body.write_b(false); // no binary data - body.write_b(false); // 64-flag - body.write_b(false); // xref dependent - body.write_rc(0x00); // trailing unknown - let bits = crate::string_stream::tests::bits_of(&body); - let payload = crate::string_stream::tests::build_payload(&bits, &["AcadAnnotative"]); - let a = decode_modern_split_stream(&payload, 8, Version::R2018).unwrap(); - assert_eq!(a.header.name, "AcadAnnotative"); - assert_eq!(a.unknown, 0); - } -} diff --git a/src/tables/ltype.rs b/src/tables/ltype.rs index 0605a28b..771e5427 100644 --- a/src/tables/ltype.rs +++ b/src/tables/ltype.rs @@ -280,174 +280,3 @@ fn skip_to(c: &mut BitCursor<'_>, bit: usize) -> Result<()> { } Ok(()) } - -#[cfg(test)] -mod tests { - use super::*; - use crate::bitwriter::BitWriter; - - fn write_header(w: &mut BitWriter, name: &[u8]) { - w.write_bs_u(name.len() as u16); - for b in name { - w.write_rc(*b); - } - w.write_b(false); - w.write_bs(0); - w.write_b(false); - } - - #[test] - fn roundtrip_dashed_ltype() { - let mut w = BitWriter::new(); - write_header(&mut w, b"DASHED"); - let desc = b"Dashed ___ __ "; - w.write_bs_u(desc.len() as u16); - for b in desc { - w.write_rc(*b); - } - w.write_bd(0.75); // pattern length - w.write_rc(b'A'); // alignment - w.write_rc(3); // 3 dashes - for (length, shape_flag) in [(0.5_f64, 0i16), (-0.125, 0), (0.125, 0)] { - w.write_bd(length); - w.write_bs(0); // complex shapecode - w.write_rd(0.0); // x_offset - w.write_rd(0.0); // y_offset - w.write_bd(1.0); // scale - w.write_bd(0.0); // rotation - w.write_bs(shape_flag); - } - for _ in 0..LTYPE_TEXT_AREA_BYTES { - w.write_rc(0); - } - let bytes = w.into_bytes(); - let mut c = BitCursor::new(&bytes); - let l = decode(&mut c, Version::R2000).unwrap(); - assert_eq!(l.header.name, "DASHED"); - assert_eq!(l.dashes.len(), 3); - assert_eq!(l.dashes[0].length, 0.5); - assert_eq!(l.dashes[1].length, -0.125); - assert_eq!(l.alignment, b'A'); - assert!(matches!(l.dashes[0].text, DashText::None)); - } - - #[test] - fn roundtrip_text_dash() { - let mut w = BitWriter::new(); - write_header(&mut w, b"TEXTLINE"); - w.write_bs_u(0); // empty description - w.write_bd(1.0); - w.write_rc(b'A'); - w.write_rc(1); - // Dash whose shape flag marks embedded text. §20.4.58 keeps the - // characters in the record's 256-byte text area, not inline, so - // the dash record itself is the same seven fields as any other. - w.write_bd(0.25); - w.write_bs(0); // complex shapecode - w.write_rd(0.1); - w.write_rd(-0.05); - w.write_bd(0.5); - w.write_bd(0.0); - w.write_bs(0x02); // shape flag: has text - for _ in 0..LTYPE_TEXT_AREA_BYTES { - w.write_rc(0); - } - let end = w.position_bits(); - let bytes = w.into_bytes(); - let mut c = BitCursor::new(&bytes); - let l = decode(&mut c, Version::R2000).unwrap(); - assert!(l.dashes[0].has_text()); - assert_eq!(l.dashes[0].x_offset, 0.1); - assert_eq!(l.dashes[0].y_offset, -0.05); - assert_eq!(c.position_bits(), end); - } - - #[test] - fn r2018_split_stream_ltype_reads_name_and_description_from_string_stream() { - let mut w = BitWriter::new(); - // Common object prefix: EED terminator, reactor count, - // xdictionary flag, AcDs binary-data flag. - w.write_bs_u(0); - w.write_bl(0); - w.write_b(true); - w.write_b(false); - // Common table-entry flags. - w.write_b(false); // 64 flag - w.write_b(false); // xdep - w.write_bd(1.0); // pattern length - w.write_rc(b'A'); // alignment - w.write_rc(0); // no dashes - - let bits = crate::string_stream::tests::bits_of(&w); - let payload = - crate::string_stream::tests::build_payload(&bits, &["Continuous", "Solid line"]); - let entry = decode_modern_split_stream(&payload, 8, Version::R2018).unwrap(); - assert_eq!(entry.header.name, "Continuous"); - assert_eq!(entry.description, "Solid line"); - assert_eq!(entry.alignment, b'A'); - assert!(entry.dashes.is_empty()); - } - - /// A dash record is `BD` length, `BS` shape code, two `RD` - /// offsets, `BD` scale, `BD` rotation, `BS` shape flag — §20.4.58's - /// order, with the two raw doubles in the middle. The 512-byte text - /// area follows only when some dash sets `shapeflag & 0x02`. - #[test] - fn r2018_split_stream_ltype_reads_a_dash_record() { - let mut w = BitWriter::new(); - w.write_bs_u(0); - w.write_b(true); - w.write_b(false); - w.write_b(false); - w.write_b(false); - w.write_bs(0); - w.write_bd(2.0); // pattern length - w.write_rc(b'A'); - w.write_rc(2); // two dashes - for (len, shape) in [(0.5f64, 0i16), (-0.25, 0)] { - w.write_bd(len); - w.write_bs(shape); - w.write_rd(0.0); - w.write_rd(0.0); - w.write_bd(1.0); - w.write_bd(0.0); - w.write_bs(0); // shape flag — no text area - } - let bits = crate::string_stream::tests::bits_of(&w); - let payload = crate::string_stream::tests::build_payload(&bits, &["DASHED", ""]); - let entry = decode_modern_split_stream(&payload, 8, Version::R2018).unwrap(); - assert_eq!(entry.header.name, "DASHED"); - assert_eq!(entry.pattern_length, 2.0); - assert_eq!(entry.dashes.len(), 2); - assert_eq!(entry.dashes[0].length, 0.5); - assert_eq!(entry.dashes[1].length, -0.25); - assert_eq!(entry.dashes[0].scale, 1.0); - } - - #[test] - fn rejects_oversized_dash_count() { - let mut w = BitWriter::new(); - write_header(&mut w, b"EVIL"); - w.write_rc(0); - w.write_rs(0); - w.write_bs_u(0); - w.write_bd(1.0); - w.write_rc(b'A'); - // num_dashes is an RC (u8) — 256 wraps to 0, so the cap is - // enforced at or above 256. The worst case the decoder can - // see from a malformed stream is 0xFF = 255, which is within - // the cap. We validate the check is *present* by unit-asserting - // the MAX_DASHES constant instead of trying to overflow. - w.write_rc(255); - // (don't bother filling dashes; decode will read garbage and - // return an error from the bit cursor, which is also fine.) - let bytes = w.into_bytes(); - let mut c = BitCursor::new(&bytes); - // Either returns Err from truncated stream OR from cap — both - // acceptable; we just need to confirm decode doesn't allocate - // past the cap. - let err = decode(&mut c, Version::R2000); - assert!(err.is_err(), "expected error for adversarial dash count"); - assert_eq!(MAX_DASHES, 256); - } -} diff --git a/src/tables/mod.rs b/src/tables/mod.rs index 96eec41e..74c3017f 100644 --- a/src/tables/mod.rs +++ b/src/tables/mod.rs @@ -119,30 +119,3 @@ pub(crate) fn read_tv(c: &mut BitCursor<'_>, version: Version) -> Result Ok(crate::code_page::decode_active(&bytes)) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::bitwriter::BitWriter; - - #[test] - fn roundtrip_entry_header() { - let mut w = BitWriter::new(); - // TV name - let s = b"MyLayer"; - w.write_bs_u(s.len() as u16); - for b in s { - w.write_rc(*b); - } - w.write_b(false); // 64-flag - w.write_bs(0); - w.write_b(false); // not xref dependent - let bytes = w.into_bytes(); - let mut c = BitCursor::new(&bytes); - let h = read_table_entry_header(&mut c, Version::R2000).unwrap(); - assert_eq!(h.name, "MyLayer"); - assert!(!h.flag_64); - assert_eq!(h.xref_index_plus_1, 0); - assert!(!h.is_xref_dependent); - } -} diff --git a/src/tables/style.rs b/src/tables/style.rs index eab06fbc..5f1dcb49 100644 --- a/src/tables/style.rs +++ b/src/tables/style.rs @@ -174,139 +174,3 @@ pub(crate) fn decode_modern_split_stream( bigfont_filename, }) } - -#[cfg(test)] -mod tests { - use super::*; - use crate::bitwriter::BitWriter; - - fn write_header(w: &mut BitWriter, name: &[u8]) { - w.write_bs_u(name.len() as u16); - for b in name { - w.write_rc(*b); - } - w.write_b(false); - w.write_bs(0); - w.write_b(false); - } - - #[test] - fn roundtrip_standard_style() { - let mut w = BitWriter::new(); - write_header(&mut w, b"Standard"); - w.write_b(false); // shape file - w.write_b(false); // vertical - w.write_bd(0.0); // fixed_height — prompt - w.write_bd(1.0); // width factor - w.write_bd(0.0); // oblique - w.write_rc(0); // generation normal - w.write_bd(2.5); // last_height - let font = b"arial.ttf"; - w.write_bs_u(font.len() as u16); - for b in font { - w.write_rc(*b); - } - w.write_bs_u(0); // no bigfont - let bytes = w.into_bytes(); - let mut c = BitCursor::new(&bytes); - let s = decode(&mut c, Version::R2000).unwrap(); - assert_eq!(s.header.name, "Standard"); - assert_eq!(s.width_factor, 1.0); - assert_eq!(s.last_height, 2.5); - assert!(s.font_filename.starts_with("arial")); - assert!(s.bigfont_filename.is_empty()); - assert!(!s.is_shape_file()); - assert!(!s.is_vertical()); - } - - #[test] - fn r2007_split_stream_style_reads_names_from_string_stream() { - // Data stream: common object prefix, then the STYLE field body. - let mut body = BitWriter::new(); - body.write_bs_u(0); // no EED - body.write_bl(0); // no reactors - body.write_b(true); // no xdictionary - body.write_b(false); // no binary data (R2013+) - body.write_b(true); // 64-flag - body.write_b(false); // xref dependent - body.write_b(true); // shape file - body.write_b(true); // vertical - body.write_bd(0.2); // fixed height - body.write_bd(1.0); // width factor - body.write_bd(0.0); // oblique angle - body.write_rc(0x04); // generation — upside down - body.write_bd(2.5); // last height - let bits = crate::string_stream::tests::bits_of(&body); - - let payload = crate::string_stream::tests::build_payload( - &bits, - &["Standard", "arial.ttf", "bigfont.shx"], - ); - let s = decode_modern_split_stream(&payload, 8, Version::R2018).unwrap(); - assert_eq!(s.header.name, "Standard"); - assert_eq!(s.font_filename, "arial.ttf"); - assert_eq!(s.bigfont_filename, "bigfont.shx"); - assert!(s.header.flag_64); - assert!(s.is_vertical()); - assert!(s.is_shape_file()); - assert_eq!(s.fixed_height, 0.2); - assert_eq!(s.width_factor, 1.0); - assert_eq!(s.oblique_angle, 0.0); - assert_eq!(s.generation, 0x04); - assert_eq!(s.last_height, 2.5); - } - - #[test] - fn r2007_split_stream_style_rejects_misaligned_body() { - // One extra bit in the data stream must be caught, not silently - // absorbed — the field body no longer ends on the string start. - let mut body = BitWriter::new(); - body.write_bs_u(0); - body.write_b(true); - body.write_b(false); - body.write_b(false); - body.write_b(false); - body.write_bs(0); - body.write_b(false); - body.write_b(false); - body.write_bd(0.0); - body.write_bd(1.0); - body.write_bd(0.0); - body.write_rc(0); - body.write_bd(0.0); - body.write_b(false); // stray bit - let bits = crate::string_stream::tests::bits_of(&body); - let payload = crate::string_stream::tests::build_payload(&bits, &["Standard", "", ""]); - let err = decode_modern_split_stream(&payload, 8, Version::R2018).unwrap_err(); - assert!( - format!("{err}").contains("STYLE data fields ended"), - "{err}" - ); - } - - #[test] - fn roundtrip_vertical_shape_style() { - let mut w = BitWriter::new(); - write_header(&mut w, b"TXT-V"); - w.write_b(true); // shape file - w.write_b(true); // vertical - w.write_bd(0.2); // fixed height - w.write_bd(0.9); // width factor - w.write_bd(15.0_f64.to_radians()); - w.write_rc(0x04); // upside-down - w.write_bd(0.2); - let font = b"txt.shx"; - w.write_bs_u(font.len() as u16); - for b in font { - w.write_rc(*b); - } - w.write_bs_u(0); - let bytes = w.into_bytes(); - let mut c = BitCursor::new(&bytes); - let s = decode(&mut c, Version::R2000).unwrap(); - assert!(s.is_shape_file()); - assert!(s.is_vertical()); - assert_eq!(s.generation, 0x04); - assert!((s.oblique_angle - 15.0_f64.to_radians()).abs() < 1e-12); - } -}