--- a/src/io/dwg/dwg_stream_readers/object_reader/entities.rs
+++ b/src/io/dwg/dwg_stream_readers/object_reader/entities.rs
@@ -1682,20 +1682,49 @@
     MLineData { scale_factor, justification, start_point, normal, openclosed, lines_in_style, vertex_count, vertices, style_handle }
 }
 
+/// Cap an array count against the bits actually left in the object's main
+/// stream instead of the blanket [`MAX_ARRAY_COUNT`].
+///
+/// MESH is the one entity whose arrays legitimately run past 100 000 items: a
+/// road-surface mesh in a civil drawing carries hundreds of thousands of
+/// vertices. Clamping those to the blanket cap does not merely truncate the
+/// mesh — the reader then continues from the wrong bit offset, so the face,
+/// edge and crease lists that follow decode as garbage (observed: a 100 000
+/// vertex clamp left a 14-face mesh with face sizes `[64, 0, 64, 23, 0, …]`).
+/// Bounding by the remaining bits keeps the corrupt-data protection — no
+/// unbounded allocation is possible — without mis-parsing a valid drawing.
+///
+/// `min_bits_per_item` is the shortest legal encoding of one element: a
+/// BitDouble is 2 bits at minimum (the 0.0 / 1.0 forms), so a 3BD vertex is 6
+/// and a BitLong is 2.
+fn stream_bounded_count(reader: &DwgMergedReader, raw: i32, min_bits_per_item: i64) -> i32 {
+    let raw = raw.max(0) as i64;
+    let total_bits = (reader.main().data_len() as i64).saturating_mul(8);
+    // The handle stream follows the main stream; anything past its start is not
+    // array data. handle_start() is 0 when the framing did not supply it.
+    let handle_start = reader.handle_start();
+    let end_bits = if handle_start > 0 { handle_start.min(total_bits) } else { total_bits };
+    let remaining = (end_bits - reader.position_in_bits()).max(0);
+    raw.min(remaining / min_bits_per_item.max(1)).min(i32::MAX as i64) as i32
+}
+
 pub fn read_mesh(reader: &mut DwgMergedReader) -> MeshData {
     let version = reader.read_bit_short();
     let blend_crease = reader.read_bit();
     let subdivision_level = reader.read_bit_long();
 
-    let num_verts = safe_count(reader.read_bit_long());
+    let raw_verts = reader.read_bit_long();
+    let num_verts = stream_bounded_count(reader, raw_verts, 6);
     let mut vertices = Vec::with_capacity(num_verts as usize);
     for _ in 0..num_verts { vertices.push(reader.read_3bit_double()); }
 
-    let total_face_data = safe_count(reader.read_bit_long());
+    let raw_face_data = reader.read_bit_long();
+    let total_face_data = stream_bounded_count(reader, raw_face_data, 2);
     let mut faces = Vec::new();
     let mut i = 0;
     while i < total_face_data {
-        let n = safe_count(reader.read_bit_long());
+        let raw_n = reader.read_bit_long();
+        let n = stream_bounded_count(reader, raw_n, 2);
         i += 1;
         let mut face = Vec::new();
         for _ in 0..n {
@@ -1705,7 +1734,8 @@
         faces.push(face);
     }
 
-    let num_edges = safe_count(reader.read_bit_long());
+    let raw_edges = reader.read_bit_long();
+    let num_edges = stream_bounded_count(reader, raw_edges, 4);
     let mut edges = Vec::with_capacity(num_edges as usize);
     for _ in 0..num_edges {
         let s = reader.read_bit_long();
@@ -1713,7 +1743,8 @@
         edges.push((s, e));
     }
 
-    let num_creases = safe_count(reader.read_bit_long());
+    let raw_creases = reader.read_bit_long();
+    let num_creases = stream_bounded_count(reader, raw_creases, 2);
     let mut crease_values = Vec::with_capacity(num_creases as usize);
     for _ in 0..num_creases { crease_values.push(reader.read_bit_double()); }
 
@@ -2350,14 +2381,31 @@
 pub fn read_ole2frame(reader: &mut DwgMergedReader, version: DwgVersion) -> Ole2FrameData {
     let ver = reader.read_bit_short();
     let mode = if version.r2000_plus() { reader.read_bit_short() } else { 0 };
-    // OLE binary data can be very large (embedded images/documents),
-    // so don't use safe_count (100 KB cap). Use a generous 10 MB cap instead.
     let data_len = (reader.read_bit_long().max(0) as usize).min(10_000_000);
     let data = reader.read_bytes(data_len);
     let trailing_byte = if version.r2000_plus() { reader.read_byte() } else { 3 };
-    let upper_left = reader.read_3bit_double();
-    let lower_right = reader.read_3bit_double();
+
+    let mut upper_left = Vector3::new(0.0, 0.0, 0.0);
+    let mut lower_right = Vector3::new(0.0, 0.0, 0.0);
+
+    // Extract 4-corner coordinates stored in the OLE binary data header starting at offset 2
+    if data.len() >= 66 {
+        let ul_x = f64::from_le_bytes(data[2..10].try_into().unwrap());
+        let ul_y = f64::from_le_bytes(data[10..18].try_into().unwrap());
+        let ul_z = f64::from_le_bytes(data[18..26].try_into().unwrap());
+        let lr_x = f64::from_le_bytes(data[50..58].try_into().unwrap());
+        let lr_y = f64::from_le_bytes(data[58..66].try_into().unwrap());
+        let lr_z = if data.len() >= 74 { f64::from_le_bytes(data[66..74].try_into().unwrap()) } else { 0.0 };
+
+        if ul_x.is_finite() && ul_y.is_finite() && lr_x.is_finite() && lr_y.is_finite()
+           && (ul_x != 0.0 || ul_y != 0.0 || lr_x != 0.0 || lr_y != 0.0) {
+            upper_left = Vector3::new(ul_x, ul_y, if ul_z.is_finite() { ul_z } else { 0.0 });
+            lower_right = Vector3::new(lr_x, lr_y, if lr_z.is_finite() { lr_z } else { 0.0 });
+        }
+    }
+
     let ole_type = if version.r2000_plus() { reader.read_byte() } else { 2 };
+
     Ole2FrameData { version: ver, mode, data, trailing_byte, upper_left, lower_right, ole_type }
 }
 
