Files

77 lines
2.6 KiB
Python

import fixtures
import dnfile
from dnfile.utils import LazyList
from dnfile.mdtable import TypeRefRow, MemberRefRow
def test_lazy_loading():
path = fixtures.get_data_path_by_name("hello-world.exe")
dn = dnfile.dnPE(path, clr_lazy_load=True)
dn.parse_data_directories()
assert dn.net
assert dn.net.mdtables
assert dn.net.mdtables.MemberRef
assert isinstance(dn.net.mdtables.MemberRef.rows, LazyList)
# LazyList is initialized as a list of `None`.
# list.__getitem__ bypasses lazy loading.
assert list.__getitem__(dn.net.mdtables.MemberRef.rows, 1) is None
memref_row = dn.net.mdtables.MemberRef.rows[1]
assert isinstance(memref_row, MemberRefRow)
assert memref_row.Name
# __dict__ access bypasses lazy loading.
assert "Signature" not in memref_row.__dict__
assert memref_row.Signature
assert "Signature" in memref_row.__dict__
# The first item of the rows list is a special case, because it is
# initialized without data before lazy-loading is setup.
# Make sure that it behaves the same as any other row when accessed.
# We can also verify that slicing works, since it too needs to be
# handled appropriately.
typeref_row = dn.net.mdtables.TypeRef.rows[:3:2][0]
assert isinstance(typeref_row, TypeRefRow)
assert "ResolutionScope" not in typeref_row.__dict__
# TypeRefRow.Class should trigger a full load of all tables and rows.
assert memref_row.Class
# This should not have been lazy-loaded, but will still have been loaded
# because of accessing the Class attribute.
assert "ResolutionScope" in typeref_row.__dict__
# _resources is the underlying lazy-loaded field for the ClrResource list.
assert dn.net._resources is None
assert dn.net.resources is not None
assert dn.net._resources is not None
def test_non_lazy_loading():
path = fixtures.get_data_path_by_name("hello-world.exe")
dn = dnfile.dnPE(path, clr_lazy_load=False)
dn.parse_data_directories()
assert dn.net
assert dn.net.mdtables
assert dn.net.mdtables.MemberRef
assert not isinstance(dn.net.mdtables.MemberRef.rows, LazyList)
# list.__getitem__ would bypass any lazy loading.
memref_row = list.__getitem__(dn.net.mdtables.MemberRef.rows, 1)
assert isinstance(memref_row, MemberRefRow)
# __dict__ access would bypass any lazy loading.
assert "Signature" in memref_row.__dict__
typeref_row = dn.net.mdtables.TypeRef.rows[0]
assert isinstance(typeref_row, TypeRefRow)
assert "ResolutionScope" in typeref_row.__dict__
# _resources is the underlying field that would be lazy-loaded.
assert dn.net._resources is not None