@@ -810,35 +810,39 @@ impl<'a> Iterator for POGOEntryIterator<'a> {
810810 Err ( error) => return Some ( Err ( error. into ( ) ) ) ,
811811 } ;
812812
813+ // Use >= to avoid empty slice, that we want to emit an error early here for
814+ // malformed name in a POGO entry.
813815 if offset >= self . data . len ( ) {
814816 return Some ( Err ( error:: Error :: Malformed ( format ! (
815- "Offset {:#x} is too big for containing name field of POGO entry (rva {:#x} and size {:#X})" ,
816- offset, rva, size
817+ "Offset {offset:#x} is too big for containing name field of POGO entry (rva {rva:#x} and size {size:#X})" ,
817818 ) ) ) ) ;
818819 }
819820 let name = match self . data [ offset..] . iter ( ) . position ( |& b| b == 0 ) {
820821 Some ( pos) => {
821- if offset + pos as usize >= self . data . len ( ) {
822+ // + 1 nul
823+ let Some ( name) = self . data . gread_with :: < & [ u8 ] > ( & mut offset, pos + 1 ) . ok ( ) else {
822824 return Some ( Err ( error:: Error :: Malformed ( format ! (
823- "Null-terminator for POGO entry (rva {:#x} and size {:#X}) found but exceeds iterator buffer" ,
824- rva, size
825+ "Null-terminator for POGO entry (rva {rva:#x} and size {size:#X}) found but exceeds iterator buffer" ,
825826 ) ) ) ) ;
826- }
827- let name = & self . data [ offset..offset + pos + 1 ] ;
828- offset = offset + pos + 1 ;
829- // Align to the next u32 boundary
830- offset = ( offset + 3 ) & !3 ; // Round up to the nearest multiple of 4
827+ } ;
828+ // Round up to the nearest multiple of 4
829+ offset = ( offset + 3 ) & !3 ;
831830 name
832831 }
833832 None => {
834833 return Some ( Err ( error:: Error :: Malformed ( format ! (
835- "Cannot find null-terimnator for POGO entry (rva {:#x} and size {:#X})" ,
836- rva, size
834+ "Cannot find null-terminator for POGO entry (rva {rva:#x} and size {size:#X})" ,
837835 ) )
838836 . into ( ) ) ) ;
839837 }
840838 } ;
841839
840+ if offset > self . data . len ( ) {
841+ return Some ( Err ( error:: Error :: Malformed ( format ! (
842+ "Offset {offset:#x} exceeds buffer length {:#x}" ,
843+ self . data. len( )
844+ ) ) ) ) ;
845+ }
842846 self . data = & self . data [ offset..] ;
843847 Some ( Ok ( POGOInfoEntry { rva, size, name } ) )
844848 }
@@ -853,7 +857,8 @@ mod tests {
853857 IMAGE_DEBUG_TYPE_CODEVIEW , IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS , IMAGE_DEBUG_TYPE_ILTCG ,
854858 IMAGE_DEBUG_TYPE_POGO , IMAGE_DEBUG_TYPE_REPRO , IMAGE_DEBUG_TYPE_VC_FEATURE ,
855859 IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT , IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE ,
856- ImageDebugDirectory , POGO_SIGNATURE_SIZE , POGOInfoEntry , ReproInfo , VCFeatureInfo ,
860+ ImageDebugDirectory , POGO_SIGNATURE_SIZE , POGOEntryIterator , POGOInfoEntry , ReproInfo ,
861+ VCFeatureInfo ,
857862 } ;
858863
859864 const NO_DEBUG_DIRECTORIES_BIN : & [ u8 ] =
@@ -1100,4 +1105,42 @@ mod tests {
11001105 ] ;
11011106 assert_eq ! ( entries, entries_expect) ;
11021107 }
1108+
1109+ #[ rustfmt:: skip]
1110+ const MALFORMED_POGO_NAME : & [ u8 ; 83 ] = & [
1111+ // Entry 1: .text$mn
1112+ 0x00 , 0x10 , 0x00 , 0x00 , // RVA: 0x00001000
1113+ 0x03 , 0x00 , 0x00 , 0x00 , // Size: 0x00000003
1114+ 0x2e , 0x74 , 0x65 , 0x78 , // Name: ".text$mn\0"
1115+ 0x74 , 0x24 , 0x6d , 0x6e ,
1116+ 0x00 , 0x00 , 0x00 , 0x00 ,
1117+ // Entry 2: .rdata
1118+ 0x00 , 0x20 , 0x00 , 0x00 , // RVA: 0x00002000
1119+ 0xa8 , 0x00 , 0x00 , 0x00 , // Size: 0x000000A8
1120+ 0x2e , 0x72 , 0x64 , 0x61 , // Name: ".rdata\0"
1121+ 0x74 , 0x61 , 0x00 , 0x00 ,
1122+ // Entry 3: .rdata$voltmd
1123+ 0xa8 , 0x20 , 0x00 , 0x00 , // RVA: 0x000020A8
1124+ 0x18 , 0x00 , 0x00 , 0x00 , // Size: 0x00000018
1125+ 0x2e , 0x72 , 0x64 , 0x61 , // Name: ".rdata$voltmd\0"
1126+ 0x74 , 0x61 , 0x24 , 0x76 ,
1127+ 0x6f , 0x6c , 0x74 , 0x6d ,
1128+ 0x64 , 0x00 , 0x00 , 0x00 ,
1129+ // Entry 4: .rdata$zzzdbg
1130+ 0xc0 , 0x20 , 0x00 , 0x00 , // RVA: 0x000020C0
1131+ 0xcc , 0x00 , 0x00 , 0x00 , // Size: 0x000000CC
1132+ 0x2e , 0x72 , 0x64 , 0x61 , // Name: ".rdata$zzzdbg\0"
1133+ 0x74 , 0x61 , 0x24 , 0x7a ,
1134+ 0x7a , 0x7a , 0x64 , 0x62 ,
1135+ 0x67 , 0x00 , 0x00 , /* truncated 0x00 */
1136+ ] ;
1137+
1138+ #[ test]
1139+ #[ should_panic = "Malformed(\" Offset 0x18 exceeds buffer length 0x17\" )" ]
1140+ fn parse_debug_pogo_malformed_name ( ) {
1141+ let entries = POGOEntryIterator {
1142+ data : MALFORMED_POGO_NAME ,
1143+ } ;
1144+ let _ = entries. collect :: < Result < Vec < _ > , _ > > ( ) . unwrap ( ) ;
1145+ }
11031146}
0 commit comments