@@ -289,7 +289,7 @@ impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> {
289289#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
290290pub struct ArangeEntry {
291291 segment : Option < u64 > ,
292- address : u64 ,
292+ range : Range ,
293293 length : u64 ,
294294}
295295
@@ -313,10 +313,13 @@ impl ArangeEntry {
313313 } else {
314314 0
315315 } ;
316- let address = input. read_address ( address_size) ?;
316+ let begin = input. read_address ( address_size) ?;
317317 let length = input. read_address ( address_size) ?;
318+ // Calculate end now so that we can handle overflow.
319+ // TODO: handle 32-bit address overflow as well.
320+ let end = begin. checked_add ( length) . ok_or ( Error :: AddressOverflow ) ?;
318321
319- match ( segment, address , length) {
322+ match ( segment, begin , length) {
320323 // This is meant to be a null terminator, but in practice it can occur
321324 // before the end, possibly due to a linker omitting a function and
322325 // leaving an unrelocated entry.
@@ -327,7 +330,7 @@ impl ArangeEntry {
327330 } else {
328331 None
329332 } ,
330- address ,
333+ range : Range { begin , end } ,
331334 length,
332335 } ) ) ,
333336 }
@@ -342,7 +345,7 @@ impl ArangeEntry {
342345 /// Return the beginning address of this arange.
343346 #[ inline]
344347 pub fn address ( & self ) -> u64 {
345- self . address
348+ self . range . begin
346349 }
347350
348351 /// Return the length of this arange.
@@ -354,10 +357,7 @@ impl ArangeEntry {
354357 /// Return the range.
355358 #[ inline]
356359 pub fn range ( & self ) -> Range {
357- Range {
358- begin : self . address ,
359- end : self . address . wrapping_add ( self . length ) ,
360- }
360+ self . range
361361 }
362362}
363363
@@ -576,7 +576,10 @@ mod tests {
576576 entry,
577577 Some ( ArangeEntry {
578578 segment: None ,
579- address: 0x0403_0201 ,
579+ range: Range {
580+ begin: 0x0403_0201 ,
581+ end: 0x0403_0201 + 0x0807_0605 ,
582+ } ,
580583 length: 0x0807_0605 ,
581584 } )
582585 ) ;
@@ -609,7 +612,10 @@ mod tests {
609612 entry,
610613 Some ( ArangeEntry {
611614 segment: Some ( 0x1817_1615_1413_1211 ) ,
612- address: 0x0403_0201 ,
615+ range: Range {
616+ begin: 0x0403_0201 ,
617+ end: 0x0403_0201 + 0x0807_0605 ,
618+ } ,
613619 length: 0x0807_0605 ,
614620 } )
615621 ) ;
@@ -642,9 +648,35 @@ mod tests {
642648 entry,
643649 Some ( ArangeEntry {
644650 segment: None ,
645- address: 0x0403_0201 ,
651+ range: Range {
652+ begin: 0x0403_0201 ,
653+ end: 0x0403_0201 + 0x0807_0605 ,
654+ } ,
646655 length: 0x0807_0605 ,
647656 } )
648657 ) ;
649658 }
659+
660+ #[ test]
661+ fn test_parse_entry_overflow ( ) {
662+ let encoding = Encoding {
663+ format : Format :: Dwarf32 ,
664+ version : 2 ,
665+ address_size : 8 ,
666+ } ;
667+ let segment_size = 0 ;
668+ #[ rustfmt:: skip]
669+ let buf = [
670+ // Address.
671+ 0x01 , 0x02 , 0x03 , 0x04 , 0x00 , 0x00 , 0x00 , 0x80 ,
672+ // Length.
673+ 0x05 , 0x06 , 0x07 , 0x08 , 0x00 , 0x00 , 0x00 , 0x80 ,
674+ // Next tuple.
675+ 0x09
676+ ] ;
677+ let rest = & mut EndianSlice :: new ( & buf, LittleEndian ) ;
678+ let entry = ArangeEntry :: parse ( rest, encoding, segment_size) ;
679+ assert_eq ! ( * rest, EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian ) ) ;
680+ assert_eq ! ( entry, Err ( Error :: AddressOverflow ) ) ;
681+ }
650682}
0 commit comments