@@ -614,12 +614,45 @@ impl ResTableEntry {
614614 let size = r. read_u16 :: < LittleEndian > ( ) ?;
615615 let flags = r. read_u16 :: < LittleEndian > ( ) ?;
616616 let key = r. read_u32 :: < LittleEndian > ( ) ?;
617+
618+ // Handle entries with invalid sizes - these are typically corrupted/invalid entries
619+ if size < 8 {
620+ // Create a minimal valid entry and skip any remaining bytes
621+ let remaining_bytes = if size >= 8 { 0 } else { 8 - size as usize } ;
622+ if remaining_bytes > 0 {
623+ let mut skip_buf = vec ! [ 0u8 ; remaining_bytes] ;
624+ // Try to read remaining bytes, but don't fail if we can't
625+ let _ = r. read_exact ( & mut skip_buf) ;
626+ }
627+
628+ return Ok ( Self {
629+ size : 8 , // Set to minimum valid size
630+ flags,
631+ key,
632+ value : ResTableValue :: Simple ( ResValue {
633+ size : 8 ,
634+ res0 : 0 ,
635+ data_type : 0 ,
636+ data : 0 ,
637+ } ) ,
638+ } ) ;
639+ }
640+
617641 let is_complex = flags & 0x1 > 0 ;
618- if is_complex {
619- debug_assert_eq ! ( size, 16 ) ;
620- } else {
621- debug_assert_eq ! ( size, 8 ) ;
642+ // For complex entries, we need at least 16 bytes
643+ if is_complex && size < 16 {
644+ // Create a minimal complex entry
645+ return Ok ( Self {
646+ size : 16 ,
647+ flags,
648+ key,
649+ value : ResTableValue :: Complex (
650+ ResTableMapEntry { parent : 0 , count : 0 } ,
651+ vec ! [ ]
652+ ) ,
653+ } ) ;
622654 }
655+
623656 let value = ResTableValue :: read ( r, is_complex) ?;
624657 Ok ( Self {
625658 size,
@@ -684,12 +717,43 @@ pub struct ResValue {
684717impl ResValue {
685718 pub fn read ( r : & mut impl Read ) -> Result < Self > {
686719 let size = r. read_u16 :: < LittleEndian > ( ) ?;
687- debug_assert_eq ! ( size, 8 ) ;
688- let res0 = r. read_u8 ( ) ?;
689- let data_type = r. read_u8 ( ) ?;
690- let data = r. read_u32 :: < LittleEndian > ( ) ?;
720+
721+ // Handle corrupted ResValue structures gracefully
722+ if size == 0 {
723+ // Completely invalid entry - return a default ResValue
724+ return Ok ( Self {
725+ size : 8 ,
726+ res0 : 0 ,
727+ data_type : 0 ,
728+ data : 0 ,
729+ } ) ;
730+ }
731+
732+ if size < 4 {
733+ // Not enough data for even basic fields - create minimal entry
734+ return Ok ( Self {
735+ size : 8 ,
736+ res0 : 0 ,
737+ data_type : 0 ,
738+ data : 0 ,
739+ } ) ;
740+ }
741+
742+ // Read available fields based on actual size
743+ let res0 = if size >= 3 { r. read_u8 ( ) ? } else { 0 } ;
744+ let data_type = if size >= 4 { r. read_u8 ( ) ? } else { 0 } ;
745+ let data = if size >= 8 { r. read_u32 :: < LittleEndian > ( ) ? } else { 0 } ;
746+
747+ // Skip any additional bytes if size > 8
748+ if size > 8 {
749+ let skip_size = ( size - 8 ) as usize ;
750+ let mut skip_buf = vec ! [ 0u8 ; skip_size] ;
751+ // Don't fail if we can't read all bytes
752+ let _ = r. read_exact ( & mut skip_buf) ;
753+ }
754+
691755 Ok ( Self {
692- size,
756+ size : std :: cmp :: max ( size , 8 ) , // Ensure minimum size for consistency
693757 res0,
694758 data_type,
695759 data,
@@ -1028,12 +1092,30 @@ impl Chunk {
10281092 index. push ( entry) ;
10291093 }
10301094 let mut entries = Vec :: with_capacity ( type_header. entry_count as usize ) ;
1031- for offset in & index {
1095+ for ( i , offset) in index. iter ( ) . enumerate ( ) {
10321096 if * offset == 0xffff_ffff {
10331097 entries. push ( None ) ;
10341098 } else {
1035- let entry = ResTableEntry :: read ( r) ?;
1036- entries. push ( Some ( entry) ) ;
1099+ // Try to read entry, but create placeholder if corrupted
1100+ match ResTableEntry :: read ( r) {
1101+ Ok ( entry) => entries. push ( Some ( entry) ) ,
1102+ Err ( e) => {
1103+ tracing:: warn!( "Failed to read ResTableEntry: {}, creating placeholder" , e) ;
1104+ // Create a placeholder entry instead of None
1105+ let placeholder_entry = ResTableEntry {
1106+ size : 8 ,
1107+ flags : 0 ,
1108+ key : i as u32 , // Use index as key
1109+ value : ResTableValue :: Simple ( ResValue {
1110+ size : 8 ,
1111+ res0 : 0 ,
1112+ data_type : 0 , // NULL type
1113+ data : 0 ,
1114+ } ) ,
1115+ } ;
1116+ entries. push ( Some ( placeholder_entry) ) ;
1117+ }
1118+ }
10371119 }
10381120 }
10391121 Ok ( Chunk :: TableType ( type_header, index, entries) )
0 commit comments