1313
1414import struct as _struct
1515import logging
16- from typing import Dict , List , Tuple , Union , Optional
16+ from typing import Dict , List , Tuple , Union , Optional , overload
1717from binascii import hexlify as _hexlify
18+ from collections .abc import Sequence
1819
1920from pefile import MAX_STRING_LENGTH , Structure
2021
@@ -268,6 +269,8 @@ def get(self, index, encoding="utf-16") -> Optional[UserString]:
268269
269270class HeapItemGuid (base .HeapItem ):
270271
272+ ITEM_SIZE = 128 // 8 # number of bytes in a guid
273+
271274 def __init__ (self , data : bytes , rva : Optional [int ] = None ):
272275 super ().__init__ (data , rva )
273276
@@ -288,7 +291,7 @@ def __repr__(self):
288291 return f"HeapItemGuid(data={ self .__data__ } ,rva={ self .rva } )"
289292
290293
291- class GuidHeap (base .ClrHeap ):
294+ class GuidHeap (base .ClrHeap , Sequence ):
292295 offset_size = 0
293296
294297 def get_str (self , index , as_bytes = False ):
@@ -302,21 +305,48 @@ def get_str(self, index, as_bytes=False):
302305
303306 return str (item )
304307
305- def get (self , index ) -> Optional [HeapItemGuid ]:
306- if index is None or index < 1 :
308+ def get (self , index : int ) -> Optional [HeapItemGuid ]:
309+ if not isinstance (index , int ):
310+ raise IndexError (f"unexpected type: { type (index )} " )
311+
312+ # 1-based indexing
313+ if index < 1 or index > len (self ):
307314 return None
308315
309- size = 128 // 8 # number of bytes in a guid
310316 # offset into the GUID stream
311- offset = (index - 1 ) * size
317+ offset = (index - 1 ) * HeapItemGuid . ITEM_SIZE
312318
313- if offset + size > len (self .__data__ ):
314- raise IndexError ("index out of range" )
315-
316- item = HeapItemGuid (self .__data__ [offset :offset + size ], self .rva + offset )
319+ item = HeapItemGuid (self .__data__ [offset :offset + HeapItemGuid .ITEM_SIZE ], self .rva + offset )
317320
318321 return item
319322
323+ def __len__ (self ) -> int :
324+ return len (self .__data__ ) // HeapItemGuid .ITEM_SIZE
325+
326+ @overload
327+ def __getitem__ (self , i : int ) -> HeapItemGuid :
328+ ...
329+
330+ @overload
331+ def __getitem__ (self , i : slice ) -> List [HeapItemGuid ]:
332+ ...
333+
334+ def __getitem__ (self , i ):
335+ if isinstance (i , int ):
336+ if i < 0 :
337+ # convert negative index into positive
338+ index0 = len (self ) + i
339+ else :
340+ index0 = i
341+ item = self .get (index0 + 1 )
342+ if item is None :
343+ raise IndexError (f"unexpected index: { i } " )
344+ return item
345+ elif isinstance (i , slice ):
346+ start , stop , step = i .indices (len (self ))
347+ return [self [index ] for index in range (start , stop , step )]
348+ raise IndexError (f"unexpected type '{ type (i )} '" )
349+
320350
321351class MDTablesStruct (Structure ):
322352 Reserved_1 : int
0 commit comments