2727 GoDataFloat ,
2828 GoDataInteger ,
2929 GoDataMap ,
30+ GoDataNilInterface ,
3031 GoDataPointer ,
3132 GoDataSlice ,
3233 GoDataString ,
@@ -273,7 +274,7 @@ def get_underlying_type(self, depth: int) -> str:
273274 def extract_at (self , info : ExtractInfo , addr : pointer , dereferenced_pointers : set [pointer ], depth : int ) -> GoData :
274275 val = safe_read_unsigned (info , addr , info .ptr_size )
275276 if val is not None :
276- sign_bit = 1 << (info .ptr_size - 1 )
277+ sign_bit = 1 << (( info .ptr_size * 8 ) - 1 )
277278 # convert unsigned to signed
278279 val -= (val & sign_bit ) << 1
279280 return GoDataInteger (heuristic = Confidence .CERTAIN .to_float (), value = val )
@@ -454,7 +455,7 @@ class GoTypeArray(GoType):
454455 length : int
455456
456457 def populate (self , type_section : bytes , offset : int , info : PopulateInfo ) -> Union [list [int ], None ]:
457- ( sub_elem , sup_slice , this_len ) = struct .unpack_from ("<" + info .ptr_specifier * 3 , type_section , offset )
458+ sub_elem , sup_slice , this_len = struct .unpack_from ("<" + info .ptr_specifier * 3 , type_section , offset )
458459 self .child_addr = sub_elem
459460 self .length = this_len
460461 return [sub_elem , sup_slice ]
@@ -516,7 +517,7 @@ class GoTypeChan(GoType):
516517 direction : int
517518
518519 def populate (self , type_section : bytes , offset : int , info : PopulateInfo ) -> Union [list [int ], None ]:
519- ( sub_elem , direction ) = struct .unpack_from ("<" + info .ptr_specifier * 2 , type_section , offset )
520+ sub_elem , direction = struct .unpack_from ("<" + info .ptr_specifier * 2 , type_section , offset )
520521 self .child_addr = sub_elem
521522 self .direction = direction
522523 return [sub_elem ]
@@ -552,7 +553,7 @@ class GoTypeFunc(GoType):
552553
553554 def populate (self , type_section : bytes , offset : int , info : PopulateInfo ) -> Union [list [int ], None ]:
554555 # the size of param count fields and the uncommon offset addition is NOT pointer size dependent.
555- ( num_param_in , num_param_out ) = struct .unpack_from ("<HH" , type_section , offset )
556+ num_param_in , num_param_out = struct .unpack_from ("<HH" , type_section , offset )
556557
557558 # We consumed 32 bits. On 32-bit, read the next byte: on 64-bit, need 32 bits of padding.
558559 offset += info .ptr_size
@@ -625,16 +626,16 @@ class GoTypeInterface(GoType):
625626
626627 def populate (self , type_section : bytes , offset : int , info : PopulateInfo ) -> Union [list [pointer ], None ]:
627628 self .methods = []
628- ( go_min_version , _ ) = self .version
629- ( methods_base , methods_len ) = struct .unpack_from (
629+ go_min_version , _ = self .version
630+ methods_base , methods_len = struct .unpack_from (
630631 "<" + info .ptr_specifier * 2 , type_section , offset + info .ptr_size
631632 )
632633 # Each method structure in the methods table is a struct of two 32-bit integers.
633634 for i in range (methods_len ):
634635 imethod_ptr = methods_base + i * 8
635636 if info .types <= imethod_ptr < info .etypes :
636637 imethod_offset = imethod_ptr - info .types
637- ( name_off , type_off ) = struct .unpack_from ("<II" , type_section , imethod_offset )
638+ name_off , type_off = struct .unpack_from ("<II" , type_section , imethod_offset )
638639
639640 name_off += 1
640641 if go_min_version <= 16 :
@@ -692,12 +693,21 @@ def extract_at(self, info: ExtractInfo, addr: pointer, dereferenced_pointers: se
692693 fail_nicely = True
693694 type_ptr = safe_read_unsigned (info , itab_ptr + info .ptr_size , info .ptr_size )
694695
695- # Treat this like dereferencing a typed pointer.
696696 if type_ptr is not None :
697- header = TypeHeader ()
698- extractor = GoTypePointer (header = header , version = self .version )
699- extractor .child_type = info .type_structs .get (type_ptr )
700- extracted = extractor .extract_at (info , addr + info .ptr_size , dereferenced_pointers , depth )
697+ # Treat this like dereferencing a typed pointer.
698+ if type_ptr > 0 :
699+ interface_type = info .type_structs .get (type_ptr )
700+ if interface_type is not None :
701+ data_pointer = safe_read_unsigned (info , addr + info .ptr_size , info .ptr_size )
702+ if data_pointer is not None :
703+ extracted = interface_type .extract_at (info , data_pointer , dereferenced_pointers , depth )
704+ else :
705+ extracted = GoDataBad (heuristic = Confidence .JUNK .to_float ())
706+ else :
707+ extracted = GoDataBad (heuristic = Confidence .JUNK .to_float ())
708+ else :
709+ # Nil interface
710+ extracted = GoDataNilInterface (heuristic = Confidence .HIGH .to_float ())
701711
702712 if extracted is None :
703713 if fail_nicely :
@@ -715,7 +725,7 @@ class GoTypeMap(GoType):
715725 bucket_type : Union [GoType , None ]
716726
717727 def populate (self , type_section : bytes , offset : int , info : PopulateInfo ) -> Union [list [pointer ], None ]:
718- ( self .key_addr , self .child_addr , self .bucket_addr ) = struct .unpack_from (
728+ self .key_addr , self .child_addr , self .bucket_addr = struct .unpack_from (
719729 "<" + info .ptr_specifier * 3 , type_section , offset
720730 )
721731 self .key_type = None
@@ -740,7 +750,7 @@ def extract_at(self, info: ExtractInfo, addr: pointer, dereferenced_pointers: se
740750 extracted : Union [GoData , None ] = None
741751
742752 if self .bucket_type is not None :
743- ( go_min_version , _ ) = self .version
753+ go_min_version , _ = self .version
744754 # Minimum version is only lifted to 24 if we are sure the new map implementation is being used
745755 # (the programmer can choose to use the old version even in 1.24).
746756 parser : Union [SwissMapParser , NoSwissMapParser ]
@@ -778,23 +788,22 @@ def extract_at(self, info: ExtractInfo, addr: pointer, dereferenced_pointers: se
778788 extracted : Union [GoData , None ] = None
779789
780790 if self .child_type :
781- child_ptr = safe_read_unsigned (info , addr , info .ptr_size )
782- if child_ptr is not None :
783- if child_ptr > 0 :
784- if child_ptr not in dereferenced_pointers :
785- dereferenced_pointers .add (child_ptr )
791+ if addr is not None :
792+ if addr > 0 :
793+ if addr not in dereferenced_pointers :
794+ dereferenced_pointers .add (addr )
786795 # changes to dereferenced_pointers are reflected everywhere, so we'll never dereference again
787796 # in this extraction.
788797 # this is good because we can reduce duplication of displayed information.
789- dereferenced = self .child_type .extract_at (info , child_ptr , dereferenced_pointers , depth )
798+ dereferenced = self .child_type .extract_at (info , addr , dereferenced_pointers , depth )
790799 if not isinstance (dereferenced , GoDataBad ):
791800 extracted = dereferenced
792801 else :
793802 # Then this pointer is not of this type - either memory does not exist, or data is illegal.
794- extracted = GoDataPointer (heuristic = Confidence .JUNK .to_float (), address = child_ptr )
803+ extracted = GoDataPointer (heuristic = Confidence .JUNK .to_float (), address = addr )
795804 else :
796805 # Circular references. Slightly downgrade confidence.
797- extracted = GoDataUnparsed (heuristic = Confidence .HIGH .to_float (), address = child_ptr )
806+ extracted = GoDataUnparsed (heuristic = Confidence .HIGH .to_float (), address = addr )
798807 else :
799808 # A valid, but null, pointer. Of course these come up - but downgrade the confidence.
800809 extracted = GoDataPointer (heuristic = Confidence .MEDIUM .to_float (), address = 0 )
@@ -956,16 +965,16 @@ class GoTypeStruct(GoType):
956965 fields : list [GoTypeStructField ]
957966
958967 def populate (self , type_section : bytes , offset : int , info : PopulateInfo ) -> Union [list [pointer ], None ]:
959- ( go_min_version , go_max_version ) = self .version
960- ( _ , fields_addr , fields_len ) = struct .unpack_from ("<" + info .ptr_specifier * 3 , type_section , offset )
968+ go_min_version , go_max_version = self .version
969+ _ , fields_addr , fields_len = struct .unpack_from ("<" + info .ptr_specifier * 3 , type_section , offset )
961970 self .fields = []
962971
963972 for i in range (fields_len ):
964973 # Each field struct is 3 pointers wide.
965974 addr = fields_addr + i * 3 * info .ptr_size
966975 if info .types <= addr < info .etypes :
967976 field_struct_offset = addr - info .types
968- ( field_name_ptr , field_type , field_offset ) = struct .unpack_from (
977+ field_name_ptr , field_type , field_offset = struct .unpack_from (
969978 "<" + info .ptr_specifier * 3 , type_section , field_struct_offset
970979 )
971980
@@ -1053,9 +1062,8 @@ def get_underlying_type(self, depth: int) -> str:
10531062 return "unsafe.Pointer"
10541063
10551064 def extract_at (self , info : ExtractInfo , addr : pointer , dereferenced_pointers : set [pointer ], depth : int ) -> GoData :
1056- child_ptr = safe_read_unsigned (info , addr , info .ptr_size )
1057- if child_ptr is not None :
1058- return GoDataPointer (heuristic = Confidence .CERTAIN .to_float (), address = child_ptr )
1065+ if addr is not None :
1066+ return GoDataPointer (heuristic = Confidence .CERTAIN .to_float (), address = addr )
10591067 return GoDataBad (heuristic = Confidence .JUNK .to_float ())
10601068
10611069
@@ -1376,7 +1384,7 @@ def parse(self, addr: pointer, nest_depth: int) -> GoData:
13761384 entries = None
13771385 break
13781386 # The next line is well-typed because if entries is None, then we already broke.
1379- entries .extend (from_table ) # type:ignore[union-attr]
1387+ entries .extend (from_table ) # type: ignore[union-attr]
13801388
13811389 if entries is not None and len (entries ) > 0 :
13821390 # A valid map.
0 commit comments