@@ -248,17 +248,41 @@ where
248248 } else {
249249 let mut counts = Vec :: < u64 > :: with_capacity ( data. num_counters as usize ) ;
250250 bytes = & bytes[ ( counter_offset as usize ) ..] ;
251- for _ in 0 ..( data. num_counters as usize ) {
252- let counter = if header. has_byte_coverage ( ) {
251+ if header. has_byte_coverage ( ) {
252+ if data. num_counters as usize > bytes. len ( ) {
253+ let pos = & bytes[ bytes. len ( ) ..] ;
254+ return Err ( Err :: Failure ( VerboseError :: from_error_kind (
255+ pos,
256+ ErrorKind :: Eof ,
257+ ) ) ) ;
258+ }
259+ for _ in 0 ..( data. num_counters as usize ) {
253260 let counter = bytes[ 0 ] ;
254261 bytes = & bytes[ 1 ..] ;
255- ( counter == 0 ) as u64
256- } else {
257- let ( b, counter) = nom_u64 ( header. endianness ) ( bytes) ?;
258- bytes = b;
259- counter
260- } ;
261- counts. push ( counter) ;
262+ counts. push ( ( counter == 0 ) as u64 ) ;
263+ }
264+ } else {
265+ let counters_bytes = data. num_counters as usize * size_of :: < u64 > ( ) ;
266+ if counters_bytes > bytes. len ( ) {
267+ let pos = & bytes[ bytes. len ( ) ..] ;
268+ return Err ( Err :: Failure ( VerboseError :: from_error_kind (
269+ pos,
270+ ErrorKind :: Eof ,
271+ ) ) ) ;
272+ }
273+ for _ in 0 ..( data. num_counters as usize ) {
274+ let ( count_bytes, remaining) = bytes. split_at ( size_of :: < u64 > ( ) ) ;
275+ bytes = remaining;
276+ let count_bytes = count_bytes
277+ . try_into ( )
278+ . expect ( "split_at returned exactly eight counter bytes" ) ;
279+ let counter = match header. endianness {
280+ Endianness :: Little => u64:: from_le_bytes ( count_bytes) ,
281+ Endianness :: Big => u64:: from_be_bytes ( count_bytes) ,
282+ Endianness :: Native => u64:: from_ne_bytes ( count_bytes) ,
283+ } ;
284+ counts. push ( counter) ;
285+ }
262286 }
263287 let record = InstrProfRecord {
264288 counts,
@@ -294,8 +318,8 @@ where
294318
295319 fn parse_bytes ( mut input : & [ u8 ] ) -> ParseResult < ' _ , InstrumentationProfile > {
296320 if !input. is_empty ( ) {
297- let mut result = InstrumentationProfile :: default ( ) ;
298321 let ( bytes, header) = Self :: parse_header ( input) ?;
322+ let mut result = InstrumentationProfile :: with_capacity ( header. data_len as usize ) ;
299323 // LLVM 11 and 12 are version 5. LLVM 13 is version 7
300324 let version_num = header. version ( ) ;
301325 result. version = Some ( version_num) ;
@@ -313,7 +337,7 @@ where
313337 ) ) ) ;
314338 }
315339 input = & bytes[ ( header. binary_ids_len as usize ) ..] ;
316- let mut data_section = vec ! [ ] ;
340+ let mut data_section = Vec :: with_capacity ( header . data_len as usize ) ;
317341 for _ in 0 ..header. data_len {
318342 let ( bytes, data) = ProfileData :: < T > :: parse ( input, & header) ?;
319343 debug ! ( "Parsed data section {:?}" , data) ;
@@ -334,7 +358,7 @@ where
334358 }
335359 } ;
336360 input = bytes;
337- let mut counters = vec ! [ ] ;
361+ let mut counters = Vec :: with_capacity ( data_section . len ( ) ) ;
338362 let mut counters_delta = header. counters_delta ;
339363
340364 // Okay so the counters section looks a bit hairy. So as a brief explanation.
@@ -368,7 +392,7 @@ where
368392 let ( bytes, _) = take ( counters_end) ( input) ?;
369393 input = bytes;
370394 let end_length = input. len ( ) - header. names_len as usize ;
371- let mut symtab = Symtab :: default ( ) ;
395+ let mut symtab = Symtab :: with_capacity ( data_section . len ( ) ) ;
372396 while input. len ( ) > end_length {
373397 let ( new_bytes, names) = parse_string_ref ( input) ?;
374398 debug ! (
0 commit comments