From 61910c2ca5dc63395a32acb84f8f9e8015474b22 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Mon, 30 Sep 2024 16:54:49 -0400 Subject: [PATCH] Fix ruff issues Runs `ruff format .` on the workspace. Signed-off-by: Michael Kubacki --- BasicDevTests.py | 21 +- ConfirmVersionAndTag.py | 2 +- docs/user/gen_api.py | 5 +- edk2toollib/acpi/dmar_parser.py | 325 ++--- edk2toollib/acpi/ivrs_parser.py | 1069 ++++++++------- edk2toollib/database/__init__.py | 55 +- edk2toollib/database/edk2_db.py | 12 +- edk2toollib/database/tables/__init__.py | 1 + .../database/tables/environment_table.py | 8 +- edk2toollib/database/tables/inf_table.py | 26 +- .../database/tables/instanced_fv_table.py | 15 +- .../database/tables/instanced_inf_table.py | 116 +- edk2toollib/database/tables/package_table.py | 12 +- edk2toollib/database/tables/source_table.py | 11 +- edk2toollib/gitignore_parser.py | 137 +- edk2toollib/log/ansi_handler.py | 103 +- edk2toollib/log/file_handler.py | 4 +- edk2toollib/log/junit_report_format.py | 65 +- edk2toollib/log/string_handler.py | 8 +- edk2toollib/os/uefivariablesupport.py | 139 +- edk2toollib/tpm/tpm2_defs.py | 161 +-- edk2toollib/tpm/tpm2_policy_calc.py | 71 +- edk2toollib/tpm/tpm2_simulator.py | 60 +- edk2toollib/tpm/tpm2_stream.py | 26 +- ...thenticated_variables_structure_support.py | 368 +++-- edk2toollib/uefi/bmp_object.py | 78 +- edk2toollib/uefi/edk2/build_objects/dsc.py | 226 ++-- .../uefi/edk2/build_objects/dsc_translator.py | 29 +- edk2toollib/uefi/edk2/fmp_payload_header.py | 44 +- .../uefi/edk2/ftw_working_block_format.py | 98 +- edk2toollib/uefi/edk2/guid_list.py | 17 +- edk2toollib/uefi/edk2/parsers/base_parser.py | 185 +-- .../uefi/edk2/parsers/buildreport_parser.py | 149 ++- edk2toollib/uefi/edk2/parsers/dec_parser.py | 85 +- edk2toollib/uefi/edk2/parsers/dsc_parser.py | 92 +- edk2toollib/uefi/edk2/parsers/fdf_parser.py | 33 +- edk2toollib/uefi/edk2/parsers/guid_parser.py | 66 +- edk2toollib/uefi/edk2/parsers/inf_parser.py | 94 +- .../uefi/edk2/parsers/override_parser.py | 46 +- .../uefi/edk2/parsers/targettxt_parser.py | 12 +- edk2toollib/uefi/edk2/path_utilities.py | 59 +- edk2toollib/uefi/edk2/variable_format.py | 109 +- edk2toollib/uefi/edk2/variable_policy.py | 108 +- .../edk2/variablestore_manulipulations.py | 27 +- edk2toollib/uefi/fmp_auth_header.py | 37 +- edk2toollib/uefi/fmp_capsule_header.py | 153 ++- edk2toollib/uefi/pi_firmware_file.py | 35 +- edk2toollib/uefi/pi_firmware_volume.py | 49 +- edk2toollib/uefi/status_codes.py | 61 +- edk2toollib/uefi/uefi_capsule_header.py | 43 +- edk2toollib/uefi/uefi_multi_phase.py | 37 +- edk2toollib/uefi/wincert.py | 67 +- edk2toollib/utility_functions.py | 155 ++- edk2toollib/windows/capsule/cat_generator.py | 49 +- edk2toollib/windows/capsule/inf_generator.py | 47 +- edk2toollib/windows/capsule/inf_generator2.py | 118 +- edk2toollib/windows/locate_tools.py | 35 +- edk2toollib/windows/policy/firmware_policy.py | 353 ++--- tests.unit/database/common.py | 24 +- tests.unit/database/test_edk2_db.py | 7 +- tests.unit/database/test_environment_table.py | 2 +- tests.unit/database/test_inf_table.py | 63 +- .../database/test_instanced_fv_table.py | 58 +- .../database/test_instanced_inf_table.py | 201 +-- tests.unit/database/test_source_table.py | 54 +- tests.unit/parsers/test_base_parser.py | 165 +-- tests.unit/parsers/test_dec_parser.py | 34 +- tests.unit/parsers/test_dmar_parser.py | 310 ++++- tests.unit/parsers/test_dsc_parser.py | 19 +- tests.unit/parsers/test_fdf_parser.py | 44 +- tests.unit/parsers/test_gitingore_parser.py | 222 ++-- tests.unit/parsers/test_guid_parser.py | 27 +- tests.unit/parsers/test_hash_file_parser.py | 15 +- tests.unit/parsers/test_inf_parser.py | 3 + tests.unit/parsers/test_ivrs_parser.py | 479 +++++-- tests.unit/parsers/test_override_parser.py | 61 +- tests.unit/test_ansi_handler.py | 82 +- ...thenticated_variables_structure_support.py | 1016 +++++++------- tests.unit/test_bmp_object.py | 127 +- tests.unit/test_cat_generator.py | 1 - tests.unit/test_dsc.py | 3 +- tests.unit/test_dsc_translator.py | 1 + tests.unit/test_firmware_policy.py | 32 +- tests.unit/test_fmp_capsule_header.py | 10 +- tests.unit/test_guid_list.py | 8 +- tests.unit/test_inf_generator.py | 102 +- tests.unit/test_inf_generator2.py | 123 +- tests.unit/test_junit_report_format.py | 9 +- tests.unit/test_locate_tools.py | 14 +- tests.unit/test_path_utilities.py | 234 ++-- tests.unit/test_status_codes.py | 3 +- tests.unit/test_string_handler.py | 1 - tests.unit/test_tpm2_defs.py | 11 +- tests.unit/test_tpm2_policy_calc.py | 45 +- tests.unit/test_tpm2_stream.py | 10 +- tests.unit/test_uefi_multi_phase.py | 66 +- tests.unit/test_utility_functions.py | 95 +- tests.unit/test_variable_format.py | 3 +- tests.unit/test_variable_policy.py | 28 +- tests.unit/test_wincert.py | 6 +- tests.unit/testdata/certificate_blobs.py | 1184 +++++++++-------- 101 files changed, 5897 insertions(+), 4721 deletions(-) diff --git a/BasicDevTests.py b/BasicDevTests.py index 1137ec29..7ead8e8b 100644 --- a/BasicDevTests.py +++ b/BasicDevTests.py @@ -37,12 +37,13 @@ def TestFilenameLowercase(apath): def PackageAndModuleValidCharacters(apath): - ''' check pep8 recommendations for package and module names''' + """check pep8 recommendations for package and module names""" - match = re.match('^[a-z0-9_/.]+$', apath.replace("\\", "/")) + match = re.match("^[a-z0-9_/.]+$", apath.replace("\\", "/")) if match is None: logging.critical( - f"PackageAndModuleValidCharacters failure: package or module name {apath} has something invalid") + f"PackageAndModuleValidCharacters failure: package or module name {apath} has something invalid" + ) return False return True @@ -55,7 +56,9 @@ def TestNoSpaces(apath): def TestRequiredLicense(apath): - licenses = ["SPDX-License-Identifier: BSD-2-Clause-Patent", ] + licenses = [ + "SPDX-License-Identifier: BSD-2-Clause-Patent", + ] try: with open(apath, "rb") as f_obj: contents = f_obj.read().decode() @@ -79,15 +82,15 @@ def TestRequiredLicense(apath): error = 0 for a in py_files: aRelativePath = os.path.relpath(a, os.getcwd()) - if (not TestEncodingOk(a, "ascii")): + if not TestEncodingOk(a, "ascii"): error += 1 - if (not TestFilenameLowercase(aRelativePath)): + if not TestFilenameLowercase(aRelativePath): error += 1 - if (not TestNoSpaces(aRelativePath)): + if not TestNoSpaces(aRelativePath): error += 1 - if (not TestRequiredLicense(a)): + if not TestRequiredLicense(a): error += 1 - if (not PackageAndModuleValidCharacters(aRelativePath)): # use relative path so only test within package + if not PackageAndModuleValidCharacters(aRelativePath): # use relative path so only test within package error += 1 logging.critical(f"Found {error} error(s) in {len(py_files)} file(s)") diff --git a/ConfirmVersionAndTag.py b/ConfirmVersionAndTag.py index 663c033d..a169561b 100644 --- a/ConfirmVersionAndTag.py +++ b/ConfirmVersionAndTag.py @@ -13,7 +13,7 @@ p = os.path.join(os.getcwd(), "dist") whl_files = glob.glob(os.path.join(p, "*.whl")) -if (len(whl_files) != 1): +if len(whl_files) != 1: for filename in whl_files: print(filename) raise Exception("Too many wheel files") diff --git a/docs/user/gen_api.py b/docs/user/gen_api.py index 73dae006..1a3fb17c 100644 --- a/docs/user/gen_api.py +++ b/docs/user/gen_api.py @@ -10,6 +10,7 @@ Used in conjunction with mkdocs to generate static markdown files for each file inside the edk2toollib package for ReadTheDocs hosting. """ + import glob import os @@ -37,7 +38,7 @@ def main(): filename = f"api{os.sep}{file_path}" with mkdocs_gen_files.open(filename, "w") as f: - ff = file_path.replace(os.sep, '.').replace('.md', '') + ff = file_path.replace(os.sep, ".").replace(".md", "") ff = f"edk2toollib.{ff}" print(f"::: {ff}", file=f) print(" handler: python", file=f) @@ -51,7 +52,7 @@ def main(): print(" show_source: False", file=f) # Point the "Edit on Github" button in the docs to point at the source code - edit_path = os.path.join('..', 'edk2toollib', edit_path) + edit_path = os.path.join("..", "edk2toollib", edit_path) mkdocs_gen_files.set_edit_path(filename, edit_path) with mkdocs_gen_files.open("api/.pages", "w") as f: diff --git a/edk2toollib/acpi/dmar_parser.py b/edk2toollib/acpi/dmar_parser.py index 8da02518..86339787 100644 --- a/edk2toollib/acpi/dmar_parser.py +++ b/edk2toollib/acpi/dmar_parser.py @@ -14,11 +14,12 @@ import xml.etree.ElementTree as ET from typing import Optional -DMARParserVersion = '1.01' +DMARParserVersion = "1.01" class DMARTable(object): """Object representing the DMAR Table.""" + # Header Lengths DMARHeaderLength = 48 DRDHHeaderLength = 16 @@ -27,10 +28,10 @@ class DMARTable(object): ANDDHeaderLength = 8 DeviceScopeHeaderLength = 6 - def __init__(self, data: bytes) -> 'DMARTable': + def __init__(self, data: bytes) -> "DMARTable": """Inits the object.""" self.dmar_table = self.AcpiTableHeader(data) - self.data = data[DMARTable.DMARHeaderLength:] + self.data = data[DMARTable.DMARHeaderLength :] while len(self.data) > 0: # Get type and length of remapping struct remapping_header = self.RemappingStructHeader(self.data) @@ -50,18 +51,18 @@ def __init__(self, data: bytes) -> 'DMARTable': remapping_header = self.ANDDStruct(self.data, remapping_header.Length) self.dmar_table.ANDDCount += 1 else: - print('Reserved remapping struct found in DMAR table') + print("Reserved remapping struct found in DMAR table") sys.exit(-1) self.dmar_table.SubStructs.append(remapping_header) # Add to XML - self.data = self.data[remapping_header.Length:] + self.data = self.data[remapping_header.Length :] self.xml = self.toXml() def toXml(self) -> ET.Element: """Converts the object to an xml representation.""" - root = ET.Element('DMAR Table') + root = ET.Element("DMAR Table") root.append(self.dmar_table.toXml()) for sub in self.dmar_table.SubStructs: root.append(sub.toXml()) @@ -85,7 +86,7 @@ def ANDDCount(self) -> int: """Returns the amount of ANDD in the DMAR table.""" return self.dmar_table.ANDDCount - def CheckRMRRCount(self, goldenxml: Optional[ET.Element]=None) -> bool: + def CheckRMRRCount(self, goldenxml: Optional[ET.Element] = None) -> bool: """Verifies all RMRR paths are in the golden XML.""" goldenignores = set() @@ -95,7 +96,7 @@ def CheckRMRRCount(self, goldenxml: Optional[ET.Element]=None) -> bool: goldenfile = ET.parse(goldenxml) goldenroot = goldenfile.getroot() for RMRR in goldenroot: - goldenignores.add(RMRR.find('Path').text.lower()) + goldenignores.add(RMRR.find("Path").text.lower()) for RMRR in self.dmar_table.RMRRlist: if RMRR.getPath() not in goldenignores: @@ -106,22 +107,25 @@ def CheckRMRRCount(self, goldenxml: Optional[ET.Element]=None) -> bool: class AcpiTableHeader(object): """Object representing the ACPI Table Header.""" - STRUCT_FORMAT = '=4sIBB6s8sI4sIBB' + + STRUCT_FORMAT = "=4sIBB6s8sI4sIBB" size = struct.calcsize(STRUCT_FORMAT) - def __init__(self, header_byte_array: bytes) -> 'DMARTable.AcpiTableHeader': + def __init__(self, header_byte_array: bytes) -> "DMARTable.AcpiTableHeader": """Inits the object.""" - (self.Signature, - self.Length, - self.Revision, - self.Checksum, - self.OEMID, - self.OEMTableID, - self.OEMRevision, - self.CreatorID, - self.CreatorRevision, - self.HostAddressWidth, - self.Flags) = struct.unpack_from(DMARTable.AcpiTableHeader.STRUCT_FORMAT, header_byte_array) + ( + self.Signature, + self.Length, + self.Revision, + self.Checksum, + self.OEMID, + self.OEMTableID, + self.OEMRevision, + self.CreatorID, + self.CreatorRevision, + self.HostAddressWidth, + self.Flags, + ) = struct.unpack_from(DMARTable.AcpiTableHeader.STRUCT_FORMAT, header_byte_array) self.DMARBit = self.Flags & 0x4 self.ANDDCount = 0 @@ -142,34 +146,46 @@ def __str__(self) -> str: Creator ID : %s Creator Revision : 0x%08X Host Address Width : 0x%02X - Flags : 0x%02X\n""" % (self.Signature, self.Length, self.Revision, self.Checksum, - self.OEMID, self.OEMTableID, self.OEMRevision, self.CreatorID, - self.CreatorRevision, self.HostAddressWidth, self.Flags) + Flags : 0x%02X\n""" % ( + self.Signature, + self.Length, + self.Revision, + self.Checksum, + self.OEMID, + self.OEMTableID, + self.OEMRevision, + self.CreatorID, + self.CreatorRevision, + self.HostAddressWidth, + self.Flags, + ) def toXml(self) -> ET.Element: """Converts the object to an xml representation.""" - xml_repr = ET.Element('AcpiTableHeader') - xml_repr.set('Signature', '%s' % self.Signature) - xml_repr.set('Length', '0x%X' % self.Length) - xml_repr.set('Revision', '0x%X' % self.Revision) - xml_repr.set('Checksum', '0x%X' % self.Checksum) - xml_repr.set('OEMID', '%s' % self.OEMID) - xml_repr.set('OEMTableID', '%s' % self.OEMTableID) - xml_repr.set('OEMRevision', '0x%X' % self.OEMRevision) - xml_repr.set('CreatorID', '%s' % self.CreatorID) - xml_repr.set('CreatorRevision', '0x%X' % self.CreatorRevision) - xml_repr.set('HostAddressWidth', '0x%X' % self.HostAddressWidth) - xml_repr.set('Flags', '0x%X' % self.Flags) + xml_repr = ET.Element("AcpiTableHeader") + xml_repr.set("Signature", "%s" % self.Signature) + xml_repr.set("Length", "0x%X" % self.Length) + xml_repr.set("Revision", "0x%X" % self.Revision) + xml_repr.set("Checksum", "0x%X" % self.Checksum) + xml_repr.set("OEMID", "%s" % self.OEMID) + xml_repr.set("OEMTableID", "%s" % self.OEMTableID) + xml_repr.set("OEMRevision", "0x%X" % self.OEMRevision) + xml_repr.set("CreatorID", "%s" % self.CreatorID) + xml_repr.set("CreatorRevision", "0x%X" % self.CreatorRevision) + xml_repr.set("HostAddressWidth", "0x%X" % self.HostAddressWidth) + xml_repr.set("Flags", "0x%X" % self.Flags) return xml_repr class RemappingStructHeader(object): """Generic remapping struct header.""" - STRUCT_FORMAT = '=HH' - def __init__(self, header_byte_array: bytes) -> 'DMARTable.RemappingStructHeader': + STRUCT_FORMAT = "=HH" + + def __init__(self, header_byte_array: bytes) -> "DMARTable.RemappingStructHeader": """Inits the object.""" - (self.Type, - self.Length) = struct.unpack_from(DMARTable.RemappingStructHeader.STRUCT_FORMAT, header_byte_array) + (self.Type, self.Length) = struct.unpack_from( + DMARTable.RemappingStructHeader.STRUCT_FORMAT, header_byte_array + ) def __str__(self) -> str: """String representation of the object.""" @@ -181,45 +197,43 @@ def __str__(self) -> str: class DRHDStruct(RemappingStructHeader): """Object representing the DRHD struct.""" - STRUCT_FORMAT = '=HHBBHQ' # spell-checker: disable-line - def __init__(self, header_byte_array: bytes, length: int) -> 'DMARTable.DRHDStruct': + STRUCT_FORMAT = "=HHBBHQ" # spell-checker: disable-line + + def __init__(self, header_byte_array: bytes, length: int) -> "DMARTable.DRHDStruct": """Inits the object.""" - (self.Type, - self.Length, - self.Flags, - self.Reserved, - self.SegmentNumber, - self.RegisterBaseAddress) = struct.unpack_from(DMARTable.DRHDStruct.STRUCT_FORMAT, header_byte_array) + (self.Type, self.Length, self.Flags, self.Reserved, self.SegmentNumber, self.RegisterBaseAddress) = ( + struct.unpack_from(DMARTable.DRHDStruct.STRUCT_FORMAT, header_byte_array) + ) # Get Sub Structs self.DeviceScope = list() - header_byte_array = header_byte_array[DMARTable.DRDHHeaderLength:] + header_byte_array = header_byte_array[DMARTable.DRDHHeaderLength :] bytes_left = self.Length - DMARTable.DRDHHeaderLength while bytes_left > 0: device_scope = DMARTable.DeviceScopeStruct(header_byte_array) - header_byte_array = header_byte_array[device_scope.Length:] + header_byte_array = header_byte_array[device_scope.Length :] bytes_left -= device_scope.Length self.DeviceScope.append(device_scope) def toXml(self) -> ET.Element: """Converts the object to an xml representation.""" - xml_repr = ET.Element('DRHD') - xml_repr.set('Type', '0x%X' % self.Type) - xml_repr.set('Length', '0x%X' % self.Length) - xml_repr.set('Flags', '0x%X' % self.Flags) - xml_repr.set('Reserved', '0x%X' % self.Reserved) - xml_repr.set('SegmentNumber', '0x%X' % self.SegmentNumber) - xml_repr.set('RegisterBaseAddress', '0x%X' % self.RegisterBaseAddress) + xml_repr = ET.Element("DRHD") + xml_repr.set("Type", "0x%X" % self.Type) + xml_repr.set("Length", "0x%X" % self.Length) + xml_repr.set("Flags", "0x%X" % self.Flags) + xml_repr.set("Reserved", "0x%X" % self.Reserved) + xml_repr.set("SegmentNumber", "0x%X" % self.SegmentNumber) + xml_repr.set("RegisterBaseAddress", "0x%X" % self.RegisterBaseAddress) # Add SubStructs for item in self.DeviceScope: xml_subitem = ET.SubElement(xml_repr, item.TypeString) - xml_subitem.set('Type', '0x%X' % item.Type) - xml_subitem.set('Length', '0x%X' % item.Length) - xml_subitem.set('Reserved', '0x%X' % item.Reserved) - xml_subitem.set('EnumerationID', '0x%X' % item.EnumerationID) - xml_subitem.set('StartBusNumber', '0x%X' % item.StartBusNumber) + xml_subitem.set("Type", "0x%X" % item.Type) + xml_subitem.set("Length", "0x%X" % item.Length) + xml_subitem.set("Reserved", "0x%X" % item.Reserved) + xml_subitem.set("EnumerationID", "0x%X" % item.EnumerationID) + xml_subitem.set("StartBusNumber", "0x%X" % item.StartBusNumber) return xml_repr @@ -242,25 +256,27 @@ def __str__(self) -> str: class RMRRStruct(RemappingStructHeader): """Object representing the RMRR struct.""" - STRUCT_FORMAT = '=HHHHQQ' # spell-checker: disable-line - def __init__(self, header_byte_array: bytes, length: int) -> 'DMARTable.RMRRStruct': + STRUCT_FORMAT = "=HHHHQQ" # spell-checker: disable-line + + def __init__(self, header_byte_array: bytes, length: int) -> "DMARTable.RMRRStruct": """Inits the object.""" - (self.Type, - self.Length, - self.Reserved, - self.SegmentNumber, - self.ReservedMemoryBaseAddress, - self.ReservedMemoryRegionLimitAddress) = struct.unpack_from(DMARTable.RMRRStruct.STRUCT_FORMAT, - header_byte_array) + ( + self.Type, + self.Length, + self.Reserved, + self.SegmentNumber, + self.ReservedMemoryBaseAddress, + self.ReservedMemoryRegionLimitAddress, + ) = struct.unpack_from(DMARTable.RMRRStruct.STRUCT_FORMAT, header_byte_array) # Get Sub Structs self.DeviceScope = list() - header_byte_array = header_byte_array[DMARTable.RMRRHeaderLength:] + header_byte_array = header_byte_array[DMARTable.RMRRHeaderLength :] bytes_left = self.Length - DMARTable.RMRRHeaderLength while bytes_left > 0: device_scope = DMARTable.DeviceScopeStruct(header_byte_array) - header_byte_array = header_byte_array[device_scope.Length:] + header_byte_array = header_byte_array[device_scope.Length :] bytes_left -= device_scope.Length self.DeviceScope.append(device_scope) @@ -275,22 +291,22 @@ def getPath(self) -> str: def toXml(self) -> ET.Element: """Converts the object to an xml representation.""" - xml_repr = ET.Element('RMRR') - xml_repr.set('Type', '0x%X' % self.Type) - xml_repr.set('Length', '0x%X' % self.Length) - xml_repr.set('Reserved', '0x%X' % self.Reserved) - xml_repr.set('SegmentNumber', '0x%X' % self.SegmentNumber) - xml_repr.set('ReservedMemoryBaseAddress', '0x%X' % self.ReservedMemoryBaseAddress) - xml_repr.set('ReservedMemoryRegionLimitAddress', '0x%X' % self.ReservedMemoryRegionLimitAddress) + xml_repr = ET.Element("RMRR") + xml_repr.set("Type", "0x%X" % self.Type) + xml_repr.set("Length", "0x%X" % self.Length) + xml_repr.set("Reserved", "0x%X" % self.Reserved) + xml_repr.set("SegmentNumber", "0x%X" % self.SegmentNumber) + xml_repr.set("ReservedMemoryBaseAddress", "0x%X" % self.ReservedMemoryBaseAddress) + xml_repr.set("ReservedMemoryRegionLimitAddress", "0x%X" % self.ReservedMemoryRegionLimitAddress) # Add SubStructs for item in self.DeviceScope: xml_subitem = ET.SubElement(xml_repr, item.TypeString) - xml_subitem.set('Type', '0x%X' % item.Type) - xml_subitem.set('Length', '0x%X' % item.Length) - xml_subitem.set('Reserved', '0x%X' % item.Reserved) - xml_subitem.set('EnumerationID', '0x%X' % item.EnumerationID) - xml_subitem.set('StartBusNumber', '0x%X' % item.StartBusNumber) + xml_subitem.set("Type", "0x%X" % item.Type) + xml_subitem.set("Length", "0x%X" % item.Length) + xml_subitem.set("Reserved", "0x%X" % item.Reserved) + xml_subitem.set("EnumerationID", "0x%X" % item.EnumerationID) + xml_subitem.set("StartBusNumber", "0x%X" % item.StartBusNumber) return xml_repr @@ -303,9 +319,14 @@ def __str__(self) -> str: Reserved : 0x%04X Segment Number : 0x%04x Reserved Memory Base Address : 0x%016x - Reserved Memory Region Limit Address : 0x%016x\n""" % (self.Type, self.Length, self.Reserved, - self.SegmentNumber, self.ReservedMemoryBaseAddress, - self.ReservedMemoryRegionLimitAddress) + Reserved Memory Region Limit Address : 0x%016x\n""" % ( + self.Type, + self.Length, + self.Reserved, + self.SegmentNumber, + self.ReservedMemoryBaseAddress, + self.ReservedMemoryRegionLimitAddress, + ) for item in self.DeviceScope: retstring += str(item) @@ -314,43 +335,42 @@ def __str__(self) -> str: class ATSRStruct(RemappingStructHeader): """Object representing the ANDD struct.""" - STRUCT_FORMAT = '=HHBBH' # spell-checker: disable-line - def __init__(self, header_byte_array: bytes, length: int) -> 'DMARTable.ATSRStruct': + STRUCT_FORMAT = "=HHBBH" # spell-checker: disable-line + + def __init__(self, header_byte_array: bytes, length: int) -> "DMARTable.ATSRStruct": """Inits the object.""" - (self.Type, - self.Length, - self.Flags, - self.Reserved, - self.SegmentNumber) = struct.unpack_from(DMARTable.ATSRStruct.STRUCT_FORMAT, header_byte_array) + (self.Type, self.Length, self.Flags, self.Reserved, self.SegmentNumber) = struct.unpack_from( + DMARTable.ATSRStruct.STRUCT_FORMAT, header_byte_array + ) # Get Sub Structs self.DeviceScope = list() - header_byte_array = header_byte_array[DMARTable.ASTRHeaderLength:] + header_byte_array = header_byte_array[DMARTable.ASTRHeaderLength :] bytes_left = self.Length - DMARTable.ASTRHeaderLength while bytes_left > 0: device_scope = DMARTable.DeviceScopeStruct(header_byte_array) - header_byte_array = header_byte_array[device_scope.Length:] + header_byte_array = header_byte_array[device_scope.Length :] bytes_left -= device_scope.Length self.DeviceScope.append(device_scope) def toXml(self) -> ET.Element: """Converts the object to an xml representation.""" - xml_repr = ET.Element('ASTR') - xml_repr.set('Type', '0x%X' % self.Type) - xml_repr.set('Length', '0x%X' % self.Length) - xml_repr.set('Flags', '0x%X' % self.Flags) - xml_repr.set('Reserved', '0x%X' % self.Reserved) - xml_repr.set('SegmentNumber', '0x%X' % self.SegmentNumber) + xml_repr = ET.Element("ASTR") + xml_repr.set("Type", "0x%X" % self.Type) + xml_repr.set("Length", "0x%X" % self.Length) + xml_repr.set("Flags", "0x%X" % self.Flags) + xml_repr.set("Reserved", "0x%X" % self.Reserved) + xml_repr.set("SegmentNumber", "0x%X" % self.SegmentNumber) # Add SubStructs for item in self.DeviceScope: xml_subitem = ET.SubElement(xml_repr, item.TypeString) - xml_subitem.set('Type', '0x%X' % item.Type) - xml_subitem.set('Length', '0x%X' % item.Length) - xml_subitem.set('Reserved', '0x%X' % item.Reserved) - xml_subitem.set('EnumerationID', '0x%X' % item.EnumerationID) - xml_subitem.set('StartBusNumber', '0x%X' % item.StartBusNumber) + xml_subitem.set("Type", "0x%X" % item.Type) + xml_subitem.set("Length", "0x%X" % item.Length) + xml_subitem.set("Reserved", "0x%X" % item.Reserved) + xml_subitem.set("EnumerationID", "0x%X" % item.EnumerationID) + xml_subitem.set("StartBusNumber", "0x%X" % item.StartBusNumber) return xml_repr @@ -372,24 +392,23 @@ def __str__(self) -> str: class RHSAStruct(RemappingStructHeader): """Object representing the RHSA struct.""" - STRUCT_FORMAT = '=HHIQI' # spell-checker: disable-line - def __init__(self, header_byte_array: bytes, length: int) -> 'DMARTable.RHSAStruct': + STRUCT_FORMAT = "=HHIQI" # spell-checker: disable-line + + def __init__(self, header_byte_array: bytes, length: int) -> "DMARTable.RHSAStruct": """Inits the object.""" - (self.Type, - self.Length, - self.Reserved, - self.RegisterBaseAddress, - self.ProximityDomain) = struct.unpack_from(DMARTable.RHSAStruct.STRUCT_FORMAT, header_byte_array) + (self.Type, self.Length, self.Reserved, self.RegisterBaseAddress, self.ProximityDomain) = ( + struct.unpack_from(DMARTable.RHSAStruct.STRUCT_FORMAT, header_byte_array) + ) def toXml(self) -> ET.Element: """Converts the object to an xml representation.""" - xml_repr = ET.Element('RHSA') - xml_repr.set('Type', '0x%X' % self.Type) - xml_repr.set('Length', '0x%X' % self.Length) - xml_repr.set('Reserved', '0x%X' % self.Reserved) - xml_repr.set('RegisterBaseAddress', '0x%X' % self.RegisterBaseAddress) - xml_repr.set('ProximityDomain', '0x%X' % self.ProximityDomain) + xml_repr = ET.Element("RHSA") + xml_repr.set("Type", "0x%X" % self.Type) + xml_repr.set("Length", "0x%X" % self.Length) + xml_repr.set("Reserved", "0x%X" % self.Reserved) + xml_repr.set("RegisterBaseAddress", "0x%X" % self.RegisterBaseAddress) + xml_repr.set("ProximityDomain", "0x%X" % self.ProximityDomain) return xml_repr @@ -406,34 +425,33 @@ def __str__(self) -> str: class ANDDStruct(RemappingStructHeader): """Object representing the ANDD struct.""" - header_format = '=HH' - def __init__(self, header_byte_array: bytes, length: int) -> 'DMARTable.ANDDStruct': + header_format = "=HH" + + def __init__(self, header_byte_array: bytes, length: int) -> "DMARTable.ANDDStruct": """Inits the object.""" - self.STRUCT_FORMAT = '=B' - (self.Type, - self.Length) = struct.unpack_from(DMARTable.ANDDStruct.header_format, header_byte_array) + self.STRUCT_FORMAT = "=B" + (self.Type, self.Length) = struct.unpack_from(DMARTable.ANDDStruct.header_format, header_byte_array) # Since there is no variable of size 3 we need to manually pull into reserved self.Reserved = 0 for i in range(6, 3, -1): self.Reserved = self.Reserved << 8 - self.Reserved |= struct.unpack(" ET.Element: """Converts the object to an xml representation.""" - xml_repr = ET.Element('ANDD') - xml_repr.set('Type', '0x%X' % self.Type) - xml_repr.set('Length', '0x%X' % self.Length) - xml_repr.set('Reserved', '0x%X' % self.Reserved) - xml_repr.set('ACPIDeviceNumber', '0x%X' % self.ACPIDeviceNumber) - xml_repr.set('ACPIObjectName', '%s' % self.ACPIObjectName) + xml_repr = ET.Element("ANDD") + xml_repr.set("Type", "0x%X" % self.Type) + xml_repr.set("Length", "0x%X" % self.Length) + xml_repr.set("Reserved", "0x%X" % self.Reserved) + xml_repr.set("ACPIDeviceNumber", "0x%X" % self.ACPIDeviceNumber) + xml_repr.set("ACPIObjectName", "%s" % self.ACPIObjectName) return xml_repr @@ -450,15 +468,14 @@ def __str__(self) -> str: class DeviceScopeStruct(object): """Object representing a Device Scope.""" - STRUCT_FORMAT = '=BBHBB' # spell-checker: disable-line - def __init__(self, header_byte_array: bytes) -> 'DMARTable.DeviceScopeStruct': + STRUCT_FORMAT = "=BBHBB" # spell-checker: disable-line + + def __init__(self, header_byte_array: bytes) -> "DMARTable.DeviceScopeStruct": """Inits a DeviceScopeStruct.""" - (self.Type, - self.Length, - self.Reserved, - self.EnumerationID, - self.StartBusNumber) = struct.unpack_from(DMARTable.DeviceScopeStruct.STRUCT_FORMAT, header_byte_array) + (self.Type, self.Length, self.Reserved, self.EnumerationID, self.StartBusNumber) = struct.unpack_from( + DMARTable.DeviceScopeStruct.STRUCT_FORMAT, header_byte_array + ) assert self.Type < 6, "Reserved Device Scope Type Found" @@ -480,8 +497,12 @@ def __init__(self, header_byte_array: bytes) -> 'DMARTable.DeviceScopeStruct': offset = 6 self.Path = list() while number_path_entries > 0: - self.Path.append((struct.unpack(" str: """Returns the path.""" retstring = "%02d" % self.StartBusNumber + ":" - for (index, item) in enumerate(self.Path): + for index, item in enumerate(self.Path): retstring += "%02d" % item[0] + "." + "%01d" % item[1] if index != len(self.Path) - 1: retstring += ":" @@ -505,11 +526,17 @@ def __str__(self) -> str: \t\t Reserved : 0x%04X \t\t Enumeration ID : 0x%02x \t\t Start Bus Number : 0x%02x - \t\t Path : """ % (self.TypeString, self.Type, self.Length, self.Reserved, - self.EnumerationID, self.StartBusNumber) + \t\t Path : """ % ( + self.TypeString, + self.Type, + self.Length, + self.Reserved, + self.EnumerationID, + self.StartBusNumber, + ) retstring += "%02d" % self.StartBusNumber + ":" - for (index, item) in enumerate(self.Path): + for index, item in enumerate(self.Path): retstring += "%02d" % item[0] + "." + "%01d" % item[1] if index != len(self.Path) - 1: retstring += ":" diff --git a/edk2toollib/acpi/ivrs_parser.py b/edk2toollib/acpi/ivrs_parser.py index c572a12a..d6fa8134 100644 --- a/edk2toollib/acpi/ivrs_parser.py +++ b/edk2toollib/acpi/ivrs_parser.py @@ -13,13 +13,14 @@ from enum import IntEnum from typing import Optional -IVRSParserVersion = '1.00' +IVRSParserVersion = "1.00" # spell-checker:ignore IVMD, IOMMUEFR class IVRS_TABLE(object): """Object representing a IVRS Table.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE": """Inits an empty object.""" self.acpi_header = None self.SubStructs = list() @@ -30,46 +31,53 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE': def Decode(self, data: bytes) -> None: """Loads data into the object from the header_byte_array.""" - self.acpi_header = IVRS_TABLE.ACPI_TABLE_HEADER(data[:IVRS_TABLE.ACPI_TABLE_HEADER.struct_format_size]) + self.acpi_header = IVRS_TABLE.ACPI_TABLE_HEADER(data[: IVRS_TABLE.ACPI_TABLE_HEADER.struct_format_size]) # Start from the end of ACPI header, but store the parsed length for verification t_length = self.acpi_header.Length self.acpi_header.Length = IVRS_TABLE.ACPI_TABLE_HEADER.struct_format_size - t_data = data[IVRS_TABLE.ACPI_TABLE_HEADER.struct_format_size:] + t_data = data[IVRS_TABLE.ACPI_TABLE_HEADER.struct_format_size :] # sanity check on incoming data Checksum8 = IVRS_TABLE.validateChecksum8(data) - if (Checksum8 != 0): - raise Exception('Incoming data checksum does not add up: checksum field %x, calculated is %x' % - (self.acpi_header.Checksum, Checksum8)) + if Checksum8 != 0: + raise Exception( + "Incoming data checksum does not add up: checksum field %x, calculated is %x" + % (self.acpi_header.Checksum, Checksum8) + ) while len(t_data) > 0: # Get type and length of remapping struct remapping_header = self.REMAPPING_STRUCT_HEADER(t_data) # Parse remapping struct - if (remapping_header.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_10H) or\ - (remapping_header.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_11H) or\ - (remapping_header.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_40H): + if ( + (remapping_header.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_10H) + or (remapping_header.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_11H) + or (remapping_header.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_40H) + ): remapping_header = self.IVHD_STRUCT(t_data) self.addIVHDEntry(remapping_header) - elif (remapping_header.Type == IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_20H) or\ - (remapping_header.Type == IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_21H) or\ - (remapping_header.Type == IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_22H): - remapping_header = self.IVMD_STRUCT(t_data[:IVRS_TABLE.IVMD_STRUCT.struct_format_size]) + elif ( + (remapping_header.Type == IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_20H) + or (remapping_header.Type == IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_21H) + or (remapping_header.Type == IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_22H) + ): + remapping_header = self.IVMD_STRUCT(t_data[: IVRS_TABLE.IVMD_STRUCT.struct_format_size]) self.addIVMDEntry(remapping_header) - if (remapping_header.Type == IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_20H): + if remapping_header.Type == IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_20H: self.IVRSBit = 0 else: - print('Reserved remapping struct found in IVRS table %d' % remapping_header.Type) + print("Reserved remapping struct found in IVRS table %d" % remapping_header.Type) sys.exit(-1) # Update data position - t_data = t_data[remapping_header.Length:] + t_data = t_data[remapping_header.Length :] if (self.acpi_header.Length != t_length) or (len(t_data) != 0): - raise Exception("IVRS length does not add up. Parsed len: %d, reported len: %d" % - (t_length, self.acpi_header.Length)) + raise Exception( + "IVRS length does not add up. Parsed len: %d, reported len: %d" % (t_length, self.acpi_header.Length) + ) def Encode(self) -> bytes: r"""Serializes the object. @@ -77,7 +85,7 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - bytes_str = b'' + bytes_str = b"" # Append ACPI header bytes_str += self.acpi_header.Encode() @@ -89,7 +97,7 @@ def Encode(self) -> bytes: def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" - root = ET.Element('IVRSTable') + root = ET.Element("IVRSTable") root.append(self.acpi_header.ToXmlElementTree()) for sub in self.SubStructs: root.append(sub.ToXmlElementTree()) @@ -117,13 +125,13 @@ def updateACPISum(self) -> None: temp_sum = sum(temp_str) self.acpi_header.Checksum = (0x100 - (temp_sum & 0xFF)) & 0xFF - def addIVHDEntry(self, ivhd: 'IVRS_TABLE.IVHD_STRUCT') -> None: + def addIVHDEntry(self, ivhd: "IVRS_TABLE.IVHD_STRUCT") -> None: """Append entry to the list, update length and checksum.""" self.acpi_header.Length += len(ivhd.Encode()) self.SubStructs.append(ivhd) self.updateACPISum() - def addIVMDEntry(self, ivmd: 'IVRS_TABLE.IVMD_STRUCT') -> None: + def addIVMDEntry(self, ivmd: "IVRS_TABLE.IVMD_STRUCT") -> None: """Append entry to the list, update length and checksum.""" self.acpi_header.Length += len(ivmd.Encode()) # IVMD has to follow the corresponding IVHD, thus the list records all entries to maintain order @@ -137,10 +145,11 @@ def IVRSBitEnabled(self) -> bool: class ACPI_TABLE_HEADER(object): """Object representing a ACPI Table Header.""" - struct_format = '=4sIBB6s8sI4sIIQ' + + struct_format = "=4sIBB6s8sI4sIIQ" struct_format_size = struct.calcsize(struct_format) - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.ACPI_TABLE_HEADER': + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.ACPI_TABLE_HEADER": """Inits an empty object.""" self.Signature = None self.Length = 0 @@ -161,17 +170,19 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.ACPI_TABLE_HEADER' def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Signature, - self.Length, - self.Revision, - self.Checksum, - self.OEMID, - self.OEMTableID, - self.OEMRevision, - self.CreatorID, - self.CreatorRevision, - self.IVinfo, - self.Reserved) = struct.unpack(IVRS_TABLE.ACPI_TABLE_HEADER.struct_format, header_byte_array) + ( + self.Signature, + self.Length, + self.Revision, + self.Checksum, + self.OEMID, + self.OEMTableID, + self.OEMRevision, + self.CreatorID, + self.CreatorRevision, + self.IVinfo, + self.Reserved, + ) = struct.unpack(IVRS_TABLE.ACPI_TABLE_HEADER.struct_format, header_byte_array) self.IVRSBit = self.IVinfo & 0x02 if (self.IVinfo & 0x1E) == 0: @@ -183,74 +194,81 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - return struct.pack(self.struct_format, - self.Signature, - self.Length, - self.Revision, - self.Checksum, - self.OEMID, - self.OEMTableID, - self.OEMRevision, - self.CreatorID, - self.CreatorRevision, - self.IVinfo, - self.Reserved) + return struct.pack( + self.struct_format, + self.Signature, + self.Length, + self.Revision, + self.Checksum, + self.OEMID, + self.OEMTableID, + self.OEMRevision, + self.CreatorID, + self.CreatorRevision, + self.IVinfo, + self.Reserved, + ) def DumpInfo(self) -> None: """Prints internal information to the console.""" - print(' ACPI Table Header') - print('------------------------------------------------------------------') - print('Signature : {Signature:s}'.format(Signature=self.Signature.decode())) - print('Length : 0x{Length:08X}'.format(Length=self.Length)) - print('Revision : 0x{Revision:02X}'.format(Revision=self.Revision)) - print('Checksum : 0x{Checksum:02X}'.format(Checksum=self.Checksum)) - print('OEM ID : {OEMID:s}'.format(OEMID=self.OEMID.decode())) - print('OEM Table ID : {OEMTableID:s}'.format(OEMTableID=self.OEMTableID.decode())) - print('OEM Revision : 0x{OEMRevision:08X}'.format(OEMRevision=self.OEMRevision)) - print('Creator ID : {CreatorID:s}'.format(CreatorID=self.CreatorID.decode())) - print('Creator Revision : 0x{CreatorRevision:08X}'.format(CreatorRevision=self.CreatorRevision)) - print('IVinfo : 0x{IVinfo:08X}'.format(IVinfo=self.IVinfo)) + print(" ACPI Table Header") + print("------------------------------------------------------------------") + print("Signature : {Signature:s}".format(Signature=self.Signature.decode())) + print("Length : 0x{Length:08X}".format(Length=self.Length)) + print("Revision : 0x{Revision:02X}".format(Revision=self.Revision)) + print("Checksum : 0x{Checksum:02X}".format(Checksum=self.Checksum)) + print("OEM ID : {OEMID:s}".format(OEMID=self.OEMID.decode())) + print("OEM Table ID : {OEMTableID:s}".format(OEMTableID=self.OEMTableID.decode())) + print("OEM Revision : 0x{OEMRevision:08X}".format(OEMRevision=self.OEMRevision)) + print("Creator ID : {CreatorID:s}".format(CreatorID=self.CreatorID.decode())) + print("Creator Revision : 0x{CreatorRevision:08X}".format(CreatorRevision=self.CreatorRevision)) + print("IVinfo : 0x{IVinfo:08X}".format(IVinfo=self.IVinfo)) def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" - xml_repr = ET.Element('AcpiTableHeader') - xml_repr.set('Signature', '%s' % self.Signature) - xml_repr.set('Length', '0x%X' % self.Length) - xml_repr.set('Revision', '0x%X' % self.Revision) - xml_repr.set('Checksum', '0x%X' % self.Checksum) - xml_repr.set('OEMID', '%s' % self.OEMID) - xml_repr.set('OEMTableID', '%s' % self.OEMTableID) - xml_repr.set('OEMRevision', '0x%X' % self.OEMRevision) - xml_repr.set('CreatorID', '%s' % self.CreatorID) - xml_repr.set('CreatorRevision', '0x%X' % self.CreatorRevision) - xml_repr.set('IVinfo', '0x%X' % self.IVinfo) + xml_repr = ET.Element("AcpiTableHeader") + xml_repr.set("Signature", "%s" % self.Signature) + xml_repr.set("Length", "0x%X" % self.Length) + xml_repr.set("Revision", "0x%X" % self.Revision) + xml_repr.set("Checksum", "0x%X" % self.Checksum) + xml_repr.set("OEMID", "%s" % self.OEMID) + xml_repr.set("OEMTableID", "%s" % self.OEMTableID) + xml_repr.set("OEMRevision", "0x%X" % self.OEMRevision) + xml_repr.set("CreatorID", "%s" % self.CreatorID) + xml_repr.set("CreatorRevision", "0x%X" % self.CreatorRevision) + xml_repr.set("IVinfo", "0x%X" % self.IVinfo) return xml_repr class REMAPPING_STRUCT_HEADER(object): """Generic ReMapping Struct Header.""" - struct_format = '=B' + + struct_format = "=B" struct_format_size = struct.calcsize(struct_format) - def __init__(self, header_byte_array: bytes) -> 'IVRS_TABLE.REMAPPING_STRUCT_HEADER': + def __init__(self, header_byte_array: bytes) -> "IVRS_TABLE.REMAPPING_STRUCT_HEADER": """Inits an empty object.""" - (self.Type, ) = struct.unpack(IVRS_TABLE.REMAPPING_STRUCT_HEADER.struct_format, - header_byte_array[:IVRS_TABLE.REMAPPING_STRUCT_HEADER.struct_format_size]) + (self.Type,) = struct.unpack( + IVRS_TABLE.REMAPPING_STRUCT_HEADER.struct_format, + header_byte_array[: IVRS_TABLE.REMAPPING_STRUCT_HEADER.struct_format_size], + ) class IVHD_STRUCT(REMAPPING_STRUCT_HEADER): """Object representing a IVHD Struct.""" + # cspell:disable-next disable the spell checker from thinking this a word - struct_format = '=BBHHHQHHI' + struct_format = "=BBHHHQHHI" struct_format_size = struct.calcsize(struct_format) ex_format = "=QQ" ex_format_size = struct.calcsize(ex_format) class IVHD_TYPE(IntEnum): """IVMD_STRUCT type enum.""" + TYPE_10H = 0x10 TYPE_11H = 0x11 TYPE_40H = 0x40 - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE': + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE": """Inits an empty object.""" self.Type = None self.Flags = None @@ -271,25 +289,30 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.IVHD_STRUCT.IVHD_T def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.Flags, - t_Length, - self.DeviceID, - self.CapabilityOffset, - self.IOMMUBaseAddress, - self.SegmentGroup, - self.IOMMUInfo, - self.IOMMUFeatureInfo) = struct.unpack(IVRS_TABLE.IVHD_STRUCT.struct_format, - header_byte_array[:IVRS_TABLE.IVHD_STRUCT.struct_format_size]) + ( + self.Type, + self.Flags, + t_Length, + self.DeviceID, + self.CapabilityOffset, + self.IOMMUBaseAddress, + self.SegmentGroup, + self.IOMMUInfo, + self.IOMMUFeatureInfo, + ) = struct.unpack( + IVRS_TABLE.IVHD_STRUCT.struct_format, header_byte_array[: IVRS_TABLE.IVHD_STRUCT.struct_format_size] + ) self.Length = 0 - if (self.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_11H) or\ - (self.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_40H): - ivhd_hdr_size = (IVRS_TABLE.IVHD_STRUCT.struct_format_size + IVRS_TABLE.IVHD_STRUCT.ex_format_size) - (self.IOMMUEFRImage, self.Reserved) =\ - struct.unpack(IVRS_TABLE.IVHD_STRUCT.ex_format, - header_byte_array[IVRS_TABLE.IVHD_STRUCT.struct_format_size:ivhd_hdr_size]) + if (self.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_11H) or ( + self.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_40H + ): + ivhd_hdr_size = IVRS_TABLE.IVHD_STRUCT.struct_format_size + IVRS_TABLE.IVHD_STRUCT.ex_format_size + (self.IOMMUEFRImage, self.Reserved) = struct.unpack( + IVRS_TABLE.IVHD_STRUCT.ex_format, + header_byte_array[IVRS_TABLE.IVHD_STRUCT.struct_format_size : ivhd_hdr_size], + ) else: ivhd_hdr_size = IVRS_TABLE.IVHD_STRUCT.struct_format_size @@ -300,14 +323,15 @@ def Decode(self, header_byte_array: bytes) -> None: # Get Sub Structs while bytes_left > 0: device_scope = IVRS_TABLE.DEVICE_TABLE_ENTRY.Factory(header_byte_array) - header_byte_array = header_byte_array[device_scope.Length:] + header_byte_array = header_byte_array[device_scope.Length :] bytes_left -= device_scope.Length - if (device_scope.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_END): + if device_scope.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_END: self.addDTEEntry(device_scope) if (t_Length != self.Length) or (bytes_left != 0): - raise Exception("IVHD length does not add up. Parsed len: %d, reported len: %d" % - (self.Length, t_Length)) + raise Exception( + "IVHD length does not add up. Parsed len: %d, reported len: %d" % (self.Length, t_Length) + ) def Encode(self) -> bytes: r"""Serializes the object. @@ -315,17 +339,19 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - byte_str = b'' - byte_str += struct.pack(IVRS_TABLE.IVHD_STRUCT.struct_format, - self.Type, - self.Flags, - self.Length, - self.DeviceID, - self.CapabilityOffset, - self.IOMMUBaseAddress, - self.SegmentGroup, - self.IOMMUInfo, - self.IOMMUFeatureInfo) + byte_str = b"" + byte_str += struct.pack( + IVRS_TABLE.IVHD_STRUCT.struct_format, + self.Type, + self.Flags, + self.Length, + self.DeviceID, + self.CapabilityOffset, + self.IOMMUBaseAddress, + self.SegmentGroup, + self.IOMMUInfo, + self.IOMMUFeatureInfo, + ) if self.IOMMUEFRImage is not None: byte_str += struct.pack(IVRS_TABLE.IVHD_STRUCT.ex_format, self.IOMMUEFRImage, self.Reserved) @@ -335,27 +361,28 @@ def Encode(self) -> bytes: return byte_str - def addDTEEntry(self, dte: 'IVRS_TABLE.DEVICE_TABLE_ENTRY') -> None: + def addDTEEntry(self, dte: "IVRS_TABLE.DEVICE_TABLE_ENTRY") -> None: """Append raw data, update length. checksum will be left untouched.""" self.Length += len(dte.Encode()) self.DeviceTableEntries.append(dte) def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" - xml_repr = ET.Element('IVHD') - xml_repr.set('Type', '0x%X' % self.Type) - xml_repr.set('Flags', '0x%X' % self.Flags) - xml_repr.set('Length', '0x%X' % self.Length) - xml_repr.set('IOMMUDeviceID', '0x%X' % self.DeviceID) - xml_repr.set('CapabilityOffset', '0x%X' % self.CapabilityOffset) - xml_repr.set('IOMMUBaseAddress', '0x%X' % self.IOMMUBaseAddress) - xml_repr.set('SegmentGroup', '0x%X' % self.SegmentGroup) - xml_repr.set('IOMMUInfo', '0x%X' % self.IOMMUInfo) - xml_repr.set('IOMMUFeatureInfo', '0x%X' % self.IOMMUFeatureInfo) - - if (self.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_11H) or\ - (self.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_40H): - xml_repr.set('IOMMUEFRImage', '0x%X' % self.IOMMUEFRImage) + xml_repr = ET.Element("IVHD") + xml_repr.set("Type", "0x%X" % self.Type) + xml_repr.set("Flags", "0x%X" % self.Flags) + xml_repr.set("Length", "0x%X" % self.Length) + xml_repr.set("IOMMUDeviceID", "0x%X" % self.DeviceID) + xml_repr.set("CapabilityOffset", "0x%X" % self.CapabilityOffset) + xml_repr.set("IOMMUBaseAddress", "0x%X" % self.IOMMUBaseAddress) + xml_repr.set("SegmentGroup", "0x%X" % self.SegmentGroup) + xml_repr.set("IOMMUInfo", "0x%X" % self.IOMMUInfo) + xml_repr.set("IOMMUFeatureInfo", "0x%X" % self.IOMMUFeatureInfo) + + if (self.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_11H) or ( + self.Type == IVRS_TABLE.IVHD_STRUCT.IVHD_TYPE.TYPE_40H + ): + xml_repr.set("IOMMUEFRImage", "0x%X" % self.IOMMUEFRImage) # Add SubStructs for item in self.DeviceTableEntries: @@ -367,32 +394,34 @@ def DumpInfo(self) -> None: """Prints internal information to the console.""" print("\t IVHD") print("\t----------------------------------------------------------------") - print('\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\tFlags : 0x{Flags:02X}'.format(Flags=self.Flags)) - print('\tLength : 0x{Length:04X}'.format(Length=self.Length)) - print('\tIOMMU Device ID : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\tCapability Offset : 0x{CapabilityOffset:04X}'.format(CapabilityOffset=self.CapabilityOffset)) - print('\tIOMMU Base Address : 0x{IOMMUBaseAddress:016X}'.format(IOMMUBaseAddress=self.IOMMUBaseAddress)) - print('\tSegment Group : 0x{SegmentGroup:04X}'.format(SegmentGroup=self.SegmentGroup)) - print('\tIOMMU Info : 0x{IOMMUInfo:04X}'.format(IOMMUInfo=self.IOMMUInfo)) - print('\tIOMMU Feature Info : 0x{IOMMUFeatureInfo:08X}'.format(IOMMUFeatureInfo=self.IOMMUFeatureInfo)) + print("\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\tFlags : 0x{Flags:02X}".format(Flags=self.Flags)) + print("\tLength : 0x{Length:04X}".format(Length=self.Length)) + print("\tIOMMU Device ID : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\tCapability Offset : 0x{CapabilityOffset:04X}".format(CapabilityOffset=self.CapabilityOffset)) + print("\tIOMMU Base Address : 0x{IOMMUBaseAddress:016X}".format(IOMMUBaseAddress=self.IOMMUBaseAddress)) + print("\tSegment Group : 0x{SegmentGroup:04X}".format(SegmentGroup=self.SegmentGroup)) + print("\tIOMMU Info : 0x{IOMMUInfo:04X}".format(IOMMUInfo=self.IOMMUInfo)) + print("\tIOMMU Feature Info : 0x{IOMMUFeatureInfo:08X}".format(IOMMUFeatureInfo=self.IOMMUFeatureInfo)) for item in self.DeviceTableEntries: item.DumpInfo() class IVMD_STRUCT(REMAPPING_STRUCT_HEADER): """Object representing an IVMD Struct.""" + # cspell:disable-next disable spell checker from thinking this is a word - struct_format = '=BBHHHQQQ' + struct_format = "=BBHHHQQQ" struct_format_size = struct.calcsize(struct_format) class IVMD_TYPE(IntEnum): """IVMD_STRUCT type enum.""" + TYPE_20H = 0x20 # All peripherals TYPE_21H = 0x21 # Specified peripheral TYPE_22H = 0x22 # Peripheral range - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.IVMD_STRUCT': + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.IVMD_STRUCT": """Inits an empty object.""" self.Type = None self.Flags = None @@ -408,16 +437,18 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.IVMD_STRUCT': def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.Flags, - self.Length, - self.DeviceID, - self.AuxiliaryData, - self.Reserved, - self.IVMDStartAddress, - self.IVMDMemoryBlockLength) = struct.unpack(IVRS_TABLE.IVMD_STRUCT.struct_format, header_byte_array) + ( + self.Type, + self.Flags, + self.Length, + self.DeviceID, + self.AuxiliaryData, + self.Reserved, + self.IVMDStartAddress, + self.IVMDMemoryBlockLength, + ) = struct.unpack(IVRS_TABLE.IVMD_STRUCT.struct_format, header_byte_array) # IVMD is simple, the length is fixed, so assert if not - if (self.Length != len(header_byte_array)): + if self.Length != len(header_byte_array): raise Exception("Bad IVMD entry size %d, expecting %d" % (self.Length, len(header_byte_array))) def Encode(self) -> bytes: @@ -426,31 +457,33 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - return struct.pack(IVRS_TABLE.IVMD_STRUCT.struct_format, - self.Type, - self.Flags, - self.Length, - self.DeviceID, - self.AuxiliaryData, - self.Reserved, - self.IVMDStartAddress, - self.IVMDMemoryBlockLength) + return struct.pack( + IVRS_TABLE.IVMD_STRUCT.struct_format, + self.Type, + self.Flags, + self.Length, + self.DeviceID, + self.AuxiliaryData, + self.Reserved, + self.IVMDStartAddress, + self.IVMDMemoryBlockLength, + ) def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" - xml_repr = ET.Element('IVMD') - - xml_repr.set('Type', '0x%X' % self.Type) - xml_repr.set('Flags', '0x%X' % self.Flags) - xml_repr.set('Length', '0x%X' % self.Length) - xml_repr.set('DeviceID', '0x%X' % self.DeviceID) - if (self.Type != IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_22H): - xml_repr.set('AuxiliaryData', '0x%X' % self.AuxiliaryData) + xml_repr = ET.Element("IVMD") + + xml_repr.set("Type", "0x%X" % self.Type) + xml_repr.set("Flags", "0x%X" % self.Flags) + xml_repr.set("Length", "0x%X" % self.Length) + xml_repr.set("DeviceID", "0x%X" % self.DeviceID) + if self.Type != IVRS_TABLE.IVMD_STRUCT.IVMD_TYPE.TYPE_22H: + xml_repr.set("AuxiliaryData", "0x%X" % self.AuxiliaryData) else: - xml_repr.set('EndofRange', '0x%X' % self.AuxiliaryData) - xml_repr.set('Reserved', '0x%X' % self.Reserved) - xml_repr.set('IVMDStartAddress', '0x%X' % self.IVMDStartAddress) - xml_repr.set('IVMDMemoryBlockLength', '0x%X' % self.IVMDMemoryBlockLength) + xml_repr.set("EndofRange", "0x%X" % self.AuxiliaryData) + xml_repr.set("Reserved", "0x%X" % self.Reserved) + xml_repr.set("IVMDStartAddress", "0x%X" % self.IVMDStartAddress) + xml_repr.set("IVMDMemoryBlockLength", "0x%X" % self.IVMDMemoryBlockLength) return xml_repr @@ -458,27 +491,38 @@ def DumpInfo(self) -> None: """Prints internal information to the console.""" print("\t IVMD") print("\t----------------------------------------------------------------") - print('\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\tFlags : 0x{Flags:02X}'.format(Flags=self.Flags)) - print('\tLength : 0x{Length:04X}'.format(Length=self.Length)) - print('\tDeviceID : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\tAuxiliaryData : 0x{AuxiliaryData:04X}'. - format(AuxiliaryData=self.AuxiliaryData)) - print('\tReserved : 0x{Reserved:016X}'.format(Reserved=self.Reserved)) - print('\tIVMD Start Address : 0x{IVMDStartAddress:016X}'. - format(IVMDStartAddress=self.IVMDStartAddress)) - print('\tIVMD Memory Block Length : 0x{IVMDMemoryBlockLength:016X}'. - format(IVMDMemoryBlockLength=self.Type)) + print("\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\tFlags : 0x{Flags:02X}".format(Flags=self.Flags)) + print("\tLength : 0x{Length:04X}".format(Length=self.Length)) + print("\tDeviceID : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print( + "\tAuxiliaryData : 0x{AuxiliaryData:04X}".format( + AuxiliaryData=self.AuxiliaryData + ) + ) + print("\tReserved : 0x{Reserved:016X}".format(Reserved=self.Reserved)) + print( + "\tIVMD Start Address : 0x{IVMDStartAddress:016X}".format( + IVMDStartAddress=self.IVMDStartAddress + ) + ) + print( + "\tIVMD Memory Block Length : 0x{IVMDMemoryBlockLength:016X}".format( + IVMDMemoryBlockLength=self.Type + ) + ) class DEVICE_TABLE_ENTRY(object): """A Generic Device Table Entry.""" - struct_format = '=BHB' + + struct_format = "=BHB" struct_format_size = struct.calcsize(struct_format) dte_var_ext_format = "=8s8sBB" dte_var_len = struct_format_size + struct.calcsize(dte_var_ext_format) class DTE_TYPE(IntEnum): """Enum for Device Table Entry Types.""" + RESERVED = 0 ALL = 1 SELECT = 2 @@ -492,40 +536,41 @@ class DTE_TYPE(IntEnum): ACPI = 240 @staticmethod - def Factory(data: bytes) -> Optional['IVRS_TABLE.DEVICE_TABLE_ENTRY_SPECIAL']: + def Factory(data: bytes) -> Optional["IVRS_TABLE.DEVICE_TABLE_ENTRY_SPECIAL"]: """Factory method to generate a specific table entry type.""" - if (data is None): + if data is None: raise Exception("Invalid File stream") RemapHeader = IVRS_TABLE.REMAPPING_STRUCT_HEADER(data) Type = RemapHeader.Type - if (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RESERVED): + if Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RESERVED: return IVRS_TABLE.DEVICE_TABLE_ENTRY_RESERVED(data) - elif (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALL): + elif Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALL: return IVRS_TABLE.DEVICE_TABLE_ENTRY_ALL(data) - elif (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SELECT): + elif Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SELECT: return IVRS_TABLE.DEVICE_TABLE_ENTRY_SELECT(data) - elif (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_START): + elif Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_START: return IVRS_TABLE.DEVICE_TABLE_ENTRY_RANGE_START(data) - elif (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_SELECT): + elif Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_SELECT: return IVRS_TABLE.DEVICE_TABLE_ENTRY_ALIAS_SELECT(data) - elif (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_RANGE_START): + elif Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_RANGE_START: return IVRS_TABLE.DEVICE_TABLE_ENTRY_ALIAS_RANGE_START(data) - elif (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_SELECT): + elif Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_SELECT: return IVRS_TABLE.DEVICE_TABLE_ENTRY_EX_SELECT(data) - elif (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_RANGE_START): + elif Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_RANGE_START: return IVRS_TABLE.DEVICE_TABLE_ENTRY_EX_RANGE_START(data) - elif (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SPECIAL): + elif Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SPECIAL: return IVRS_TABLE.DEVICE_TABLE_ENTRY_SPECIAL(data) - elif (Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ACPI): + elif Type == IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ACPI: return IVRS_TABLE.DEVICE_TABLE_ENTRY_ACPI(data) else: return None class DEVICE_TABLE_ENTRY_RESERVED(object): """Object representing a Device Table Entry RESERVED.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -537,13 +582,16 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RESERVED): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RESERVED, self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RESERVED: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RESERVED, + self.Type, + ) self.TypeString = "Reserved" self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size @@ -554,30 +602,28 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - return struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) + return struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting) def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('DeviceID', '0x%X' % (self.DeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) - xml_item.set('Type', '0x%X' % self.Type) + xml_item.set("DeviceID", "0x%X" % (self.DeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) + xml_item.set("Type", "0x%X" % self.Type) return xml_item def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tDevice ID : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tDevice ID : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) class DEVICE_TABLE_ENTRY_ALL(object): """Object representing a Device Table Entry ALL.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY_ALL': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY_ALL": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -589,14 +635,16 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALL): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALL, - self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALL: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALL, + self.Type, + ) self.TypeString = "All" self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size @@ -607,30 +655,28 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - return struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) + return struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting) def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('Type', '0x%X' % self.Type) - xml_item.set('DeviceID', '0x%X' % (self.DeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) + xml_item.set("Type", "0x%X" % self.Type) + xml_item.set("DeviceID", "0x%X" % (self.DeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) return xml_item def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tDevice ID : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tDevice ID : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) class DEVICE_TABLE_ENTRY_SELECT(object): """Object representing a Device Table Entry SELECT.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY_SELECT': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY_SELECT": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -642,14 +688,16 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SELECT): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SELECT, - self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SELECT: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SELECT, + self.Type, + ) self.TypeString = "Reserved" self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size @@ -660,30 +708,28 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - return struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) + return struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting) def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('Type', '0x%X' % self.Type) - xml_item.set('DeviceID', '0x%X' % (self.DeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) + xml_item.set("Type", "0x%X" % self.Type) + xml_item.set("DeviceID", "0x%X" % (self.DeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) return xml_item def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tDevice ID : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tDevice ID : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) class DEVICE_TABLE_ENTRY_RANGE_START(object): """Object representing a Device Table Entry RANGE_START.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY_RANGE_START': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY_RANGE_START": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -695,21 +741,23 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_START): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_START, - self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_START: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_START, + self.Type, + ) self.TypeString = "Range" self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size - (Type, self.EndDeviceID, _) =\ - struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[self.Length: - (self.Length + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size)]) + (Type, self.EndDeviceID, _) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[self.Length : (self.Length + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size)], + ) if Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_END: print("Start of range does not follow end of range") sys.exit(-1) @@ -721,37 +769,39 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - byte_str = struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) - byte_str += struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_END, - self.EndDeviceID, - 0) + byte_str = struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting + ) + byte_str += struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_END, + self.EndDeviceID, + 0, + ) return byte_str def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('Type', '0x%X' % self.Type) - xml_item.set('StartofRange', '0x%X' % self.DeviceID) - xml_item.set('EndofRange', '0x%X' % (self.EndDeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) + xml_item.set("Type", "0x%X" % self.Type) + xml_item.set("StartofRange", "0x%X" % self.DeviceID) + xml_item.set("EndofRange", "0x%X" % (self.EndDeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) return xml_item def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tStart of Range : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tEnd of Range : 0x{EndDeviceID:04X}'.format(EndDeviceID=self.EndDeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tStart of Range : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tEnd of Range : 0x{EndDeviceID:04X}".format(EndDeviceID=self.EndDeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) class DEVICE_TABLE_ENTRY_ALIAS_SELECT(object): """Object representing a Device Table Entry ALIAS_SELECT.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY_ALIAS_SELECT': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY_ALIAS_SELECT": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -764,22 +814,26 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_SELECT): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_SELECT, - self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_SELECT: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_SELECT, + self.Type, + ) self.TypeString = "Alias Select" # Two DevID, one for alias, one for source - self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size +\ - IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size - (_, self.SourceDeviceID, _) =\ - struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size:self.Length]) + self.Length = ( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + ) + (_, self.SourceDeviceID, _) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size : self.Length], + ) def Encode(self) -> bytes: r"""Serializes the object. @@ -787,34 +841,34 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - byte_str = struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) + byte_str = struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting + ) byte_str += struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, 0, self.SourceDeviceID, 0) return byte_str def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('Type', '0x%X' % self.Type) - xml_item.set('DeviceID', '0x%X' % (self.DeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) - xml_item.set('SourceDeviceID', '0x%X' % (self.SourceDeviceID)) + xml_item.set("Type", "0x%X" % self.Type) + xml_item.set("DeviceID", "0x%X" % (self.DeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) + xml_item.set("SourceDeviceID", "0x%X" % (self.SourceDeviceID)) return xml_item def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tDevice ID : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) - print('\t\tSource Device ID : 0x{SourceDeviceID:04X}'.format(SourceDeviceID=self.SourceDeviceID)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tDevice ID : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) + print("\t\tSource Device ID : 0x{SourceDeviceID:04X}".format(SourceDeviceID=self.SourceDeviceID)) class DEVICE_TABLE_ENTRY_ALIAS_RANGE_START(object): """Object representing a Device Table Range Start.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY_ALIAS_RANGE_START': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY_ALIAS_RANGE_START": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -828,26 +882,30 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_RANGE_START): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_RANGE_START, - self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_RANGE_START: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ALIAS_RANGE_START, + self.Type, + ) self.TypeString = "Alias Range" # Two DevID, one for alias start, one for source start - self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size +\ - IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size - (_, self.SourceDeviceID, _) =\ - struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size:self.Length]) - (Type, self.EndDeviceID, _) =\ - struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[self.Length: - (self.Length + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size)]) + self.Length = ( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + ) + (_, self.SourceDeviceID, _) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size : self.Length], + ) + (Type, self.EndDeviceID, _) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[self.Length : (self.Length + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size)], + ) if Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_END: print("Start of range does not follow end of range") sys.exit(-1) @@ -859,40 +917,42 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - byte_str = struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) + byte_str = struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting + ) byte_str += struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, 0, self.SourceDeviceID, 0) - byte_str += struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_END, - self.EndDeviceID, - 0) + byte_str += struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_END, + self.EndDeviceID, + 0, + ) return byte_str def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('Type', '0x%X' % self.Type) - xml_item.set('StartofRange', '0x%X' % self.DeviceID) - xml_item.set('EndofRange', '0x%X' % (self.EndDeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) - xml_item.set('SourceDeviceID', '0x%X' % (self.SourceDeviceID)) + xml_item.set("Type", "0x%X" % self.Type) + xml_item.set("StartofRange", "0x%X" % self.DeviceID) + xml_item.set("EndofRange", "0x%X" % (self.EndDeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) + xml_item.set("SourceDeviceID", "0x%X" % (self.SourceDeviceID)) return xml_item def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tStart of Range : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tEnd of Range : 0x{EndDeviceID:04X}'.format(EndDeviceID=self.EndDeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) - print('\t\tSource Device ID : 0x{SourceDeviceID:04X}'.format(SourceDeviceID=self.SourceDeviceID)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tStart of Range : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tEnd of Range : 0x{EndDeviceID:04X}".format(EndDeviceID=self.EndDeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) + print("\t\tSource Device ID : 0x{SourceDeviceID:04X}".format(SourceDeviceID=self.SourceDeviceID)) class DEVICE_TABLE_ENTRY_EX_SELECT(object): """Object representing a Device Table Entry EX_SELECT.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY_EX_SELECT': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY_EX_SELECT": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -905,21 +965,25 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_SELECT): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_SELECT, - self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_SELECT: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_SELECT, + self.Type, + ) self.TypeString = "Extended Select" # Two DTE setting, one for standard setting, one for extended setting (AtsDisabled, etc.) - self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size +\ - IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size - (self.ExtendedDTESetting,) = \ - struct.unpack("=I", header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size:self.Length]) + self.Length = ( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + ) + (self.ExtendedDTESetting,) = struct.unpack( + "=I", header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size : self.Length] + ) def Encode(self) -> bytes: r"""Serializes the object. @@ -927,10 +991,9 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - byte_str = struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) + byte_str = struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting + ) # Two DTE setting, one for standard setting, one for extended setting (AtsDisabled, etc.) byte_str += struct.pack("=I", self.ExtendedDTESetting) return byte_str @@ -938,31 +1001,32 @@ def Encode(self) -> bytes: def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('Type', '0x%X' % self.Type) - xml_item.set('DeviceID', '0x%X' % (self.DeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) + xml_item.set("Type", "0x%X" % self.Type) + xml_item.set("DeviceID", "0x%X" % (self.DeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) if (self.ExtendedDTESetting & 0x80000000) != 0: - xml_item.set('ExtendedDTESetting', 'ATS requests blocked') + xml_item.set("ExtendedDTESetting", "ATS requests blocked") else: - xml_item.set('ExtendedDTESetting', 'ATS allowed') + xml_item.set("ExtendedDTESetting", "ATS allowed") return xml_item def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tDevice ID : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tDevice ID : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) if (self.ExtendedDTESetting & 0x80000000) != 0: ats_str = "ATS requests blocked" else: ats_str = "ATS allowed" - print('\t\tExtended DTE Setting : {ExtendedDTESetting:s}'.format(ExtendedDTESetting=ats_str)) + print("\t\tExtended DTE Setting : {ExtendedDTESetting:s}".format(ExtendedDTESetting=ats_str)) class DEVICE_TABLE_ENTRY_EX_RANGE_START(object): """Object representing a Device Table Entry EX_RANGE_START.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY_EX_RANGE_START': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY_EX_RANGE_START": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -974,25 +1038,29 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_RANGE_START): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_RANGE_START, - self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_RANGE_START: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.EX_RANGE_START, + self.Type, + ) self.TypeString = "Extended Range" # Two DTE setting, one for standard setting start, one for extended setting start - self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size +\ - IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size - (self.ExtendedDTESetting,) =\ - struct.unpack("=I", header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size:self.Length]) - (Type, self.EndDeviceID, _) =\ - struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[self.Length: - (self.Length + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size)]) + self.Length = ( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + ) + (self.ExtendedDTESetting,) = struct.unpack( + "=I", header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size : self.Length] + ) + (Type, self.EndDeviceID, _) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[self.Length : (self.Length + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size)], + ) if Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.RANGE_END: print("Start of range does not follow end of range") sys.exit(-1) @@ -1004,10 +1072,9 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - byte_str = struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) + byte_str = struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting + ) # Two DTE setting, one for standard setting start, one for extended setting start byte_str += struct.pack("=I", self.ExtendedDTESetting) byte_str += struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, 4, self.EndDeviceID, 0) @@ -1016,33 +1083,34 @@ def Encode(self) -> bytes: def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('Type', '0x%X' % self.Type) - xml_item.set('StartofRange', '0x%X' % self.DeviceID) - xml_item.set('EndofRange', '0x%X' % (self.EndDeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) + xml_item.set("Type", "0x%X" % self.Type) + xml_item.set("StartofRange", "0x%X" % self.DeviceID) + xml_item.set("EndofRange", "0x%X" % (self.EndDeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) if (self.ExtendedDTESetting & 0x80000000) != 0: - xml_item.set('ExtendedDTESetting', 'ATS requests blocked') + xml_item.set("ExtendedDTESetting", "ATS requests blocked") else: - xml_item.set('ExtendedDTESetting', 'ATS allowed') + xml_item.set("ExtendedDTESetting", "ATS allowed") return xml_item def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tStart of Range : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tEnd of Range : 0x{EndDeviceID:04X}'.format(EndDeviceID=self.EndDeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tStart of Range : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tEnd of Range : 0x{EndDeviceID:04X}".format(EndDeviceID=self.EndDeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) if (self.ExtendedDTESetting & 0x80000000) != 0: ats_str = "ATS requests blocked" else: ats_str = "ATS allowed" - print('\t\tExtended DTE Setting : {ExtendedDTESetting:s}'.format(ExtendedDTESetting=ats_str)) + print("\t\tExtended DTE Setting : {ExtendedDTESetting:s}".format(ExtendedDTESetting=ats_str)) class DEVICE_TABLE_ENTRY_SPECIAL(object): """Object representing a Device Table Entry Special.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY_SPECIAL': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY_SPECIAL": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -1055,22 +1123,26 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SPECIAL): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SPECIAL, - self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SPECIAL: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.SPECIAL, + self.Type, + ) self.TypeString = "Special Device" # First half for standard DTE setting, second half for special DevID and its variety (APIC, HPET, etc.) - self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size +\ - IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size - (self.Handle, self.SourceDeviceID, self.Variety) =\ - struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size:self.Length]) + self.Length = ( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size + ) + (self.Handle, self.SourceDeviceID, self.Variety) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size : self.Length], + ) def Encode(self) -> bytes: r"""Serializes the object. @@ -1078,42 +1150,40 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - byte_str = struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) + byte_str = struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting + ) # First half for standard DTE setting, second half for special DevID and its variety (APIC, HPET, etc.) - byte_str += struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Handle, - self.SourceDeviceID, - self.Variety) + byte_str += struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Handle, self.SourceDeviceID, self.Variety + ) return byte_str def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('Type', '0x%X' % self.Type) - xml_item.set('DeviceID', '0x%X' % (self.DeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) - xml_item.set('SourceDeviceID', '0x%X' % (self.SourceDeviceID)) + xml_item.set("Type", "0x%X" % self.Type) + xml_item.set("DeviceID", "0x%X" % (self.DeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) + xml_item.set("SourceDeviceID", "0x%X" % (self.SourceDeviceID)) - xml_item.set('Handle', '0x%X' % (self.Handle)) + xml_item.set("Handle", "0x%X" % (self.Handle)) if self.Variety == 1: - xml_item.set('Variety', 'IOAPIC') + xml_item.set("Variety", "IOAPIC") elif self.Variety == 2: - xml_item.set('Variety', 'HPET') + xml_item.set("Variety", "HPET") else: - xml_item.set('Variety', 'Reserved %X' % (self.Variety)) + xml_item.set("Variety", "Reserved %X" % (self.Variety)) return xml_item def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tDevice ID : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) - print('\t\tSource Device ID : 0x{SourceDeviceID:04X}'.format(SourceDeviceID=self.SourceDeviceID)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tDevice ID : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) + print("\t\tSource Device ID : 0x{SourceDeviceID:04X}".format(SourceDeviceID=self.SourceDeviceID)) if self.Variety == 1: var_str = "IOAPIC" @@ -1121,12 +1191,13 @@ def DumpInfo(self) -> None: var_str = "HPET" else: var_str = "Reserved 0x%02X" % (self.Variety) - print('\t\tHandle : 0x{Handle:02X}'.format(Handle=self.Handle)) - print('\t\tVariety : {Variety:s}'.format(Variety=var_str)) + print("\t\tHandle : 0x{Handle:02X}".format(Handle=self.Handle)) + print("\t\tVariety : {Variety:s}".format(Variety=var_str)) class DEVICE_TABLE_ENTRY_ACPI(object): """Object representing a Device Table Entry ACPI.""" - def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY_ACPI': + + def __init__(self, data: Optional[bytes] = None) -> "IVRS_TABLE.DEVICE_TABLE_ENTRY_ACPI": """Inits an empty object.""" self.Type = 0 self.DeviceID = 0 @@ -1139,30 +1210,35 @@ def __init__(self, data: Optional[bytes]=None) -> 'IVRS_TABLE.DEVICE_TABLE_ENTRY def Decode(self, header_byte_array: bytes) -> None: """Loads data into the object from the header_byte_array.""" - (self.Type, - self.DeviceID, - self.DTESetting) = struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - header_byte_array[:IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size]) - if (self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ACPI): - raise Exception("Input device type (%d) does not match expectation (%d)", - IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ACPI, - self.Type) + (self.Type, self.DeviceID, self.DTESetting) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, + header_byte_array[: IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size], + ) + if self.Type != IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ACPI: + raise Exception( + "Input device type (%d) does not match expectation (%d)", + IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ACPI, + self.Type, + ) self.TypeString = "Variable Length ACPI HID Device" - (self.HID, self.CID, self.UIDFormat, self.UIDLength) =\ - struct.unpack(IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_ext_format, - header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size: - IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_len]) + (self.HID, self.CID, self.UIDFormat, self.UIDLength) = struct.unpack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_ext_format, + header_byte_array[ + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format_size : IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_len + ], + ) self.Length = IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_len + self.UIDLength if self.UIDFormat == 0: self.UID = None elif self.UIDFormat == 1: - (self.UID,) = struct.unpack("=Q", header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_len: - self.Length]) + (self.UID,) = struct.unpack( + "=Q", header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_len : self.Length] + ) elif self.UIDFormat == 2: - (self.UID,) =\ - struct.unpack("=%ss" % self.UIDLength, - header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_len:self.Length]) + (self.UID,) = struct.unpack( + "=%ss" % self.UIDLength, header_byte_array[IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_len : self.Length] + ) def Encode(self) -> bytes: r"""Serializes the object. @@ -1170,16 +1246,13 @@ def Encode(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - byte_str = struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, - self.Type, - self.DeviceID, - self.DTESetting) + byte_str = struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.struct_format, self.Type, self.DeviceID, self.DTESetting + ) # Variable Length ACPI HID Device - byte_str += struct.pack(IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_ext_format, - self.HID, - self.CID, - self.UIDFormat, - self.UIDLength) + byte_str += struct.pack( + IVRS_TABLE.DEVICE_TABLE_ENTRY.dte_var_ext_format, self.HID, self.CID, self.UIDFormat, self.UIDLength + ) if self.UIDFormat == 1: byte_str += struct.pack("=Q", self.UID) elif self.UIDFormat == 2: @@ -1189,20 +1262,20 @@ def Encode(self) -> bytes: def ToXmlElementTree(self) -> ET.Element: """Transforms the object into an xml item and returns it.""" xml_item = ET.Element(self.TypeString.replace(" ", "")) - xml_item.set('Type', '0x%X' % self.Type) - xml_item.set('DeviceID', '0x%X' % (self.DeviceID)) - xml_item.set('DTESetting', '0x%X' % (self.DTESetting)) - - xml_item.set('HardwareID', '%s' % (self.HID)) - xml_item.set('ExtendedDTE Setting', '%s' % (self.CID)) - xml_item.set('UniqueIDFormat', '%d' % (self.UIDFormat)) - xml_item.set('UniqueIDLength', '%d' % (self.UIDLength)) + xml_item.set("Type", "0x%X" % self.Type) + xml_item.set("DeviceID", "0x%X" % (self.DeviceID)) + xml_item.set("DTESetting", "0x%X" % (self.DTESetting)) + + xml_item.set("HardwareID", "%s" % (self.HID)) + xml_item.set("ExtendedDTE Setting", "%s" % (self.CID)) + xml_item.set("UniqueIDFormat", "%d" % (self.UIDFormat)) + xml_item.set("UniqueIDLength", "%d" % (self.UIDLength)) if self.UIDFormat == 0: - xml_item.set('UniqueID', 'None') + xml_item.set("UniqueID", "None") elif self.UIDFormat == 1: - xml_item.set('UniqueID', '0x%X' % (self.UID)) + xml_item.set("UniqueID", "0x%X" % (self.UID)) elif self.UIDFormat == 2: - xml_item.set('UniqueID', '%s' % (self.UID)) + xml_item.set("UniqueID", "%s" % (self.UID)) else: print("Unrecognized UID format detected") sys.exit(-1) @@ -1210,21 +1283,21 @@ def ToXmlElementTree(self) -> ET.Element: def DumpInfo(self) -> None: """Prints internal information to the console.""" - print('\t\t {TypeString:s}'.format(TypeString=self.TypeString)) - print('\t\t--------------------------------------------------') - print('\t\tType : 0x{Type:02X}'.format(Type=self.Type)) - print('\t\tDevice ID : 0x{DeviceID:04X}'.format(DeviceID=self.DeviceID)) - print('\t\tDTE Setting : 0x{DTESetting:02X}'.format(DTESetting=self.DTESetting)) - - print('\t\tHardware ID : {HID:s}'.format(HID=self.HID.decode())) - print('\t\tExtended DTE Setting : {CID:s}'.format(CID=self.CID.decode())) - print('\t\tUnique ID Format : {UIDFormat:d}'.format(UIDFormat=self.UIDFormat)) - print('\t\tUnique ID Length : {UIDLength:d}'.format(UIDLength=self.UIDLength)) + print("\t\t {TypeString:s}".format(TypeString=self.TypeString)) + print("\t\t--------------------------------------------------") + print("\t\tType : 0x{Type:02X}".format(Type=self.Type)) + print("\t\tDevice ID : 0x{DeviceID:04X}".format(DeviceID=self.DeviceID)) + print("\t\tDTE Setting : 0x{DTESetting:02X}".format(DTESetting=self.DTESetting)) + + print("\t\tHardware ID : {HID:s}".format(HID=self.HID.decode())) + print("\t\tExtended DTE Setting : {CID:s}".format(CID=self.CID.decode())) + print("\t\tUnique ID Format : {UIDFormat:d}".format(UIDFormat=self.UIDFormat)) + print("\t\tUnique ID Length : {UIDLength:d}".format(UIDLength=self.UIDLength)) if self.UIDFormat == 0: - print('\t\tUnique ID : None') + print("\t\tUnique ID : None") elif self.UIDFormat == 1: - print('\t\tUnique ID : 0x{UID:X}'.format(UID=self.UID)) + print("\t\tUnique ID : 0x{UID:X}".format(UID=self.UID)) elif self.UIDFormat == 2: - print('\t\tUnique ID : {UID:s}'.format(UID=self.UID.decode())) + print("\t\tUnique ID : {UID:s}".format(UID=self.UID.decode())) else: raise Exception("Unrecognized UID format detected %d" % self.UIDFormat) diff --git a/edk2toollib/database/__init__.py b/edk2toollib/database/__init__.py index 5154dda6..a23613af 100644 --- a/edk2toollib/database/__init__.py +++ b/edk2toollib/database/__init__.py @@ -7,6 +7,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Core classes and methods used to interact with the database module inside edk2-pytool-library.""" + import datetime from typing import List, Optional @@ -17,36 +18,43 @@ # Association tables. Should not be used directly. Only for relationships _source_association = Table( - 'source_association', Edk2DB.Base.metadata, - Column('left_id', Integer, ForeignKey('inf.id')), - Column('right_id', Integer, ForeignKey('source.id')), + "source_association", + Edk2DB.Base.metadata, + Column("left_id", Integer, ForeignKey("inf.id")), + Column("right_id", Integer, ForeignKey("source.id")), ) _instance_source_association = Table( - 'instance_source_association', Edk2DB.Base.metadata, - Column('left_id', Integer, ForeignKey('instancedinf.id')), - Column('right_id', Integer, ForeignKey('source.id')), + "instance_source_association", + Edk2DB.Base.metadata, + Column("left_id", Integer, ForeignKey("instancedinf.id")), + Column("right_id", Integer, ForeignKey("source.id")), ) _fv_association = Table( - 'fv_association', Edk2DB.Base.metadata, - Column('left_id', Integer, ForeignKey('fv.id')), - Column('right_id', Integer, ForeignKey('instancedinf.id')), + "fv_association", + Edk2DB.Base.metadata, + Column("left_id", Integer, ForeignKey("fv.id")), + Column("right_id", Integer, ForeignKey("instancedinf.id")), ) _library_association = Table( - 'library_association', Edk2DB.Base.metadata, - Column('left_id', Integer, ForeignKey('inf.id')), - Column('right_id', Integer, ForeignKey('library.id')), + "library_association", + Edk2DB.Base.metadata, + Column("left_id", Integer, ForeignKey("inf.id")), + Column("right_id", Integer, ForeignKey("library.id")), ) _inf_association = Table( - 'inf_association', Edk2DB.Base.metadata, - Column('left_id', Integer, ForeignKey('instancedinf.id')), - Column('right_id', Integer, ForeignKey('instancedinf.id')), + "inf_association", + Edk2DB.Base.metadata, + Column("left_id", Integer, ForeignKey("instancedinf.id")), + Column("right_id", Integer, ForeignKey("instancedinf.id")), ) + class Environment(Edk2DB.Base): """A class to represent an environment in the database.""" + __tablename__ = "environment" id: Mapped[str] = mapped_column(primary_key=True) @@ -54,8 +62,10 @@ class Environment(Edk2DB.Base): version: Mapped[str] = mapped_column(String(40)) values: Mapped[List["Value"]] = relationship(back_populates="env", cascade="all, delete-orphan") + class Value(Edk2DB.Base): """A class to represent a key-value pair in the database.""" + __tablename__ = "value" env_id: Mapped[str] = mapped_column(ForeignKey("environment.id"), primary_key=True, index=True) @@ -63,8 +73,10 @@ class Value(Edk2DB.Base): value: Mapped[str] env: Mapped["Environment"] = relationship(back_populates="values") + class Inf(Edk2DB.Base): """A class to represent an INF file in the database.""" + __tablename__ = "inf" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) @@ -74,10 +86,12 @@ class Inf(Edk2DB.Base): package_name: Mapped[Optional[str]] = mapped_column(ForeignKey("package.name")) module_type: Mapped[Optional[str]] sources: Mapped[List["Source"]] = relationship(secondary=_source_association) - libraries: Mapped[List["Library"]] = relationship(secondary=_library_association) + libraries: Mapped[List["Library"]] = relationship(secondary=_library_association) + class InstancedInf(Edk2DB.Base): """A class to represent an instanced INF file in the database.""" + __tablename__ = "instancedinf" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) @@ -101,8 +115,10 @@ class InstancedInf(Edk2DB.Base): secondary=_instance_source_association, ) + class Source(Edk2DB.Base): """A class to represent a source file in the database.""" + __tablename__ = "source" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) @@ -113,15 +129,19 @@ class Source(Edk2DB.Base): comment_lines: Mapped[Optional[int]] blank_lines: Mapped[Optional[int]] + class Library(Edk2DB.Base): """A class to represent a library in the database.""" + __tablename__ = "library" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) name: Mapped[str] = mapped_column(unique=True) + class Repository(Edk2DB.Base): """A class to represent a repository in the database.""" + __tablename__ = "repository" __table_args__ = (UniqueConstraint("name", "path"),) @@ -133,6 +153,7 @@ class Repository(Edk2DB.Base): class Package(Edk2DB.Base): """A class to represent a package in the database.""" + __tablename__ = "package" __table_args__ = (UniqueConstraint("name", "path"),) @@ -142,8 +163,10 @@ class Package(Edk2DB.Base): repository: Mapped["Repository"] = relationship("Repository", back_populates="packages") repository_id: Mapped[int] = mapped_column(ForeignKey("repository.id")) + class Fv(Edk2DB.Base): """A class to represent an FV in the database.""" + __tablename__ = "fv" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) diff --git a/edk2toollib/database/edk2_db.py b/edk2toollib/database/edk2_db.py index 9ca5d66f..424ef938 100644 --- a/edk2toollib/database/edk2_db.py +++ b/edk2toollib/database/edk2_db.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """A class for interacting with a database implemented using json.""" + import logging import time import uuid @@ -24,6 +25,7 @@ class Base(DeclarativeBase): This class should be the subclass for any table model that will be used with Edk2DB. """ + class Edk2DB: """A SQLite3 database manager for a EDKII workspace. @@ -53,8 +55,10 @@ class Edk2DB: db.connection.execute("SELECT * FROM ?", table) ``` """ + Base = Base - def __init__(self: 'Edk2DB', db_path: str, pathobj: Edk2Path = None, **kwargs: dict[str,Any]) -> 'Edk2DB': + + def __init__(self: "Edk2DB", db_path: str, pathobj: Edk2Path = None, **kwargs: dict[str, Any]) -> "Edk2DB": """Initializes the database. Args: @@ -83,7 +87,7 @@ def session(self) -> Session: finally: session.close() - def register(self, *parsers: 'TableGenerator') -> None: + def register(self, *parsers: "TableGenerator") -> None: """Registers a one or more table generators. Args: @@ -113,6 +117,7 @@ def parse(self, env: dict) -> None: table.parse(session, self.pathobj, id, env) logging.debug(f"Finished in {round(time.time() - t, 2)}") + class TableGenerator: """An interface for a parser that generates a sqlite3 table maintained by Edk2DB. @@ -122,7 +127,8 @@ class TableGenerator: the parser has finished executing and has returned. Review sqlite3 documentation for more information on how to interact with the database. """ - def __init__(self, *args: Any, **kwargs: Any) -> 'TableGenerator': + + def __init__(self, *args: Any, **kwargs: Any) -> "TableGenerator": """Initialize the query with the specific settings.""" def parse(self, session: Session, pathobj: Edk2Path, id: str, env: dict) -> None: diff --git a/edk2toollib/database/tables/__init__.py b/edk2toollib/database/tables/__init__.py index 136fc1f8..e42b26a3 100644 --- a/edk2toollib/database/tables/__init__.py +++ b/edk2toollib/database/tables/__init__.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """A collection of table generators that run against the workspace.""" + from edk2toollib.database.edk2_db import TableGenerator # noqa: F401 from edk2toollib.database.tables.environment_table import EnvironmentTable # noqa: F401 from edk2toollib.database.tables.inf_table import InfTable # noqa: F401 diff --git a/edk2toollib/database/tables/environment_table.py b/edk2toollib/database/tables/environment_table.py index 59fe0493..c617bac2 100644 --- a/edk2toollib/database/tables/environment_table.py +++ b/edk2toollib/database/tables/environment_table.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """A module to run a table generator that creates or appends to a table with environment information.""" + import datetime from typing import Any @@ -18,7 +19,8 @@ class EnvironmentTable(TableGenerator): """A Workspace parser that records import environment information for a given parsing execution.""" # noqa: E501 - def __init__(self, *args: Any, **kwargs: Any) -> 'EnvironmentTable': + + def __init__(self, *args: Any, **kwargs: Any) -> "EnvironmentTable": """Initialize the query with the specific settings.""" def parse(self, session: Session, pathobj: Edk2Path, id: str, env: dict) -> None: @@ -33,6 +35,8 @@ def parse(self, session: Session, pathobj: Edk2Path, id: str, env: dict) -> None entry = Environment( id=id, date=dtime, - version=version,values = [Value(env_id = env, key=key, value=value) for key, value in env.items()]) + version=version, + values=[Value(env_id=env, key=key, value=value) for key, value in env.items()], + ) session.add(entry) diff --git a/edk2toollib/database/tables/inf_table.py b/edk2toollib/database/tables/inf_table.py index 9f152415..2747ac80 100644 --- a/edk2toollib/database/tables/inf_table.py +++ b/edk2toollib/database/tables/inf_table.py @@ -7,6 +7,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """A module to run generate a table containing information about each INF in the workspace.""" + import logging import time from pathlib import Path @@ -22,8 +23,9 @@ class InfTable(TableGenerator): """A Table Generator that parses all INF files in the workspace and generates a table.""" + # TODO: Add phase, protocol, guid, ppi, pcd tables and associations once necessary - def __init__(self, *args: Any, **kwargs: Any) -> 'InfTable': + def __init__(self, *args: Any, **kwargs: Any) -> "InfTable": """Initializes the INF Table Parser. Args: @@ -35,7 +37,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> 'InfTable': """ self.n_jobs = kwargs.get("n_jobs", -1) - def parse(self, session: Session, pathobj: Edk2Path, env_id: str, env: dict) -> None: """Parse the workspace and update the database.""" ws = Path(pathobj.WorkspacePath) @@ -73,7 +74,8 @@ def parse(self, session: Session, pathobj: Edk2Path, env_id: str, env: dict) -> logging.debug( f"{self.__class__.__name__}: Parsed {len(inf_entries)} .inf files took; " - f"{round(time.time() - start, 2)} seconds.") + f"{round(time.time() - start, 2)} seconds." + ) def _parse_file(self, filename: str, pathobj: Edk2Path) -> dict: inf_parser = InfP().SetEdk2Path(pathobj) @@ -89,10 +91,14 @@ def _parse_file(self, filename: str, pathobj: Edk2Path) -> dict: source = Path(pathobj.GetEdk2RelativePathFromAbsolutePath(str(source))).as_posix() source_list.append(source) - return (Inf( - path = Path(path).as_posix(), - guid = inf_parser.Dict.get("FILE_GUID", ""), - library_class = inf_parser.LibraryClass or None, - package_name = pkg, - module_type = inf_parser.Dict.get("MODULE_TYPE", None), - ), source_list, inf_parser.LibrariesUsed) + return ( + Inf( + path=Path(path).as_posix(), + guid=inf_parser.Dict.get("FILE_GUID", ""), + library_class=inf_parser.LibraryClass or None, + package_name=pkg, + module_type=inf_parser.Dict.get("MODULE_TYPE", None), + ), + source_list, + inf_parser.LibrariesUsed, + ) diff --git a/edk2toollib/database/tables/instanced_fv_table.py b/edk2toollib/database/tables/instanced_fv_table.py index 1b7705f0..da758ef9 100644 --- a/edk2toollib/database/tables/instanced_fv_table.py +++ b/edk2toollib/database/tables/instanced_fv_table.py @@ -7,6 +7,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """A module to generate a table containing fv information.""" + import logging import re from pathlib import Path @@ -25,9 +26,9 @@ class InstancedFvTable(TableGenerator): This table generator relies on the instanced_inf_table generator to be run first. """ # noqa: E501 - INFOPTS = re.compile(r'(RuleOverride|file_guid|version|ui|use)\s*=.+\s+(.+\.inf)', re.IGNORECASE) + INFOPTS = re.compile(r"(RuleOverride|file_guid|version|ui|use)\s*=.+\s+(.+\.inf)", re.IGNORECASE) - def __init__(self, *args: Any, **kwargs: Any) -> 'InstancedFvTable': + def __init__(self, *args: Any, **kwargs: Any) -> "InstancedFvTable": """Initialize the query with the specific settings.""" def parse(self, session: Session, pathobj: Edk2Path, env_id: str, env: dict) -> None: @@ -52,7 +53,6 @@ def parse(self, session: Session, pathobj: Edk2Path, env_id: str, env: dict) -> all_components = {inf.path: inf for inf in session.query(InstancedInf).filter_by(env=env_id, cls=None).all()} for fv in fdfp.FVs: - inf_list = [] # Some INF's have extra options. We only need the INF for inf in fdfp.FVs[fv]["Infs"]: options = InstancedFvTable.INFOPTS.findall(inf) @@ -72,15 +72,10 @@ def parse(self, session: Session, pathobj: Edk2Path, env_id: str, env: dict) -> filtered = [] for inf in inf_list: if inf not in all_components: - logging.warning(f'INF [{inf}] not found in database.') + logging.warning(f"INF [{inf}] not found in database.") else: filtered.append(inf) - fv = Fv( - env = env_id, - name = fv, - fdf = self.fdf, - infs = [all_components.get(inf) for inf in filtered] - ) + fv = Fv(env=env_id, name=fv, fdf=self.fdf, infs=[all_components.get(inf) for inf in filtered]) session.add(fv) session.commit() diff --git a/edk2toollib/database/tables/instanced_inf_table.py b/edk2toollib/database/tables/instanced_inf_table.py index b4b27ec9..48ec40f6 100644 --- a/edk2toollib/database/tables/instanced_inf_table.py +++ b/edk2toollib/database/tables/instanced_inf_table.py @@ -7,6 +7,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """A module to run the InstancedInf table generator against a dsc, adding instanced inf information to the database.""" + import logging import re from pathlib import Path @@ -21,12 +22,13 @@ class InstancedInfTable(TableGenerator): """A Table Generator that parses a single DSC file and generates a table.""" + SECTION_LIBRARY = "LibraryClasses" SECTION_COMPONENT = "Components" SECTION_REGEX = re.compile(r"\[(.*)\]") OVERRIDE_REGEX = re.compile(r"\<(.*)\>") - def __init__(self, *args: Any, **kwargs: Any) -> 'InstancedInfTable': + def __init__(self, *args: Any, **kwargs: Any) -> "InstancedInfTable": """Initialize the query with the specific settings.""" self._parsed_infs = {} @@ -83,7 +85,7 @@ def _insert_db_rows(self, session: Session, env_id: str, inf_entries: list) -> i all_repos = { (repo.name, repo.path): repo for repo in session.query(Repository).filter(Repository.path is not None).all() } - local_repo = session.query(Repository).filter_by(path = None).first() + local_repo = session.query(Repository).filter_by(path=None).first() for e in inf_entries: # Could parse a Windows INF file, which is not a EDKII INF file # and won't have a guid. GUIDS are required for INFs so we can @@ -102,39 +104,37 @@ def _insert_db_rows(self, session: Session, env_id: str, inf_entries: list) -> i if package is not None: repo = package.repository else: + def filter_search(repo: Repository) -> bool: """Return the Repository that contains the INF file.""" if repo.path is None: return False return Path(self.pathobj.WorkspacePath, repo.path).as_posix() in Path(e["FULL_PATH"]).as_posix() + repo = next( filter(filter_search, all_repos.values()), - local_repo # Default + local_repo, # Default ) rows.append( InstancedInf( - env = env_id, - path = e["PATH"], - cls = e.get("LIBRARY_CLASS"), - name = e["NAME"], - arch = e["ARCH"], - dsc = e["DSC"], - component = e["COMPONENT"], - sources = sources, - package = package, - repository = repo, + env=env_id, + path=e["PATH"], + cls=e.get("LIBRARY_CLASS"), + name=e["NAME"], + arch=e["ARCH"], + dsc=e["DSC"], + component=e["COMPONENT"], + sources=sources, + package=package, + repository=repo, ) ) session.add_all(rows) session.commit() all_libraries = { - ( - library.path, - library.arch, - library.cls, - library.component - ): library for library in session.query(InstancedInf).filter_by(env=env_id).all() + (library.path, library.arch, library.cls, library.component): library + for library in session.query(InstancedInf).filter_by(env=env_id).all() } # Link all instanced INF rows to their used libraries for row, inf in zip(rows, inf_entries): @@ -150,7 +150,7 @@ def _build_inf_table(self, dscp: DscP) -> list: This is where we merge DSC parser information with INF parser information. """ inf_entries = [] - for (inf, scope, overrides) in dscp.Components: + for inf, scope, overrides in dscp.Components: # components section scope should only contain the arch. # module_type is only needed for libraryclasses section. if "." in scope: @@ -191,7 +191,7 @@ def _parse_inf_recursively( library_dict: dict, override_dict: dict, scope: str, - visited: list[str] + visited: list[str], ) -> str: """Recurses down all libraries starting from a single INF. @@ -241,13 +241,15 @@ def _parse_inf_recursively( if instance is None or instance in visited: continue to_return += self._parse_inf_recursively( - instance, cls, component, library_dict, override_dict, scope, visited - ) + instance, cls, component, library_dict, override_dict, scope, visited + ) + # Transform path to edk2 relative form (POSIX) def to_posix(path: str) -> str: if path is None: return None return Path(path).as_posix() + library_instance_list = list(map(to_posix, library_instance_list)) source_list = [] @@ -259,33 +261,29 @@ def to_posix(path: str) -> str: source_list.append(source) # Return Paths as posix paths, which is Edk2 standard. - to_return.append({ - "DSC": Path(self.dsc).name, - "PATH": Path(inf).as_posix(), - "FULL_PATH": full_inf, - "GUID": infp.Dict.get("FILE_GUID", ""), - "NAME": infp.Dict["BASE_NAME"], - "LIBRARY_CLASS": library_class, - "COMPONENT": Path(component).as_posix(), - "MODULE_TYPE": infp.Dict["MODULE_TYPE"], - "ARCH": arch, - "PACKAGE": pkg, - "SOURCES_USED": source_list, - "LIBRARIES_USED": list(zip(library_class_list, library_instance_list)), - "PROTOCOLS_USED": [], # TODO - "GUIDS_USED": [], # TODO - "PPIS_USED": [], # TODO - "PCDS_USED": infp.PcdsUsed, - }) + to_return.append( + { + "DSC": Path(self.dsc).name, + "PATH": Path(inf).as_posix(), + "FULL_PATH": full_inf, + "GUID": infp.Dict.get("FILE_GUID", ""), + "NAME": infp.Dict["BASE_NAME"], + "LIBRARY_CLASS": library_class, + "COMPONENT": Path(component).as_posix(), + "MODULE_TYPE": infp.Dict["MODULE_TYPE"], + "ARCH": arch, + "PACKAGE": pkg, + "SOURCES_USED": source_list, + "LIBRARIES_USED": list(zip(library_class_list, library_instance_list)), + "PROTOCOLS_USED": [], # TODO + "GUIDS_USED": [], # TODO + "PPIS_USED": [], # TODO + "PCDS_USED": infp.PcdsUsed, + } + ) return to_return - def _lib_to_instance( - self, - library_class_name: str, - scope: str, - library_dict: dict, - override_dict: dict - ) -> str: + def _lib_to_instance(self, library_class_name: str, scope: str, library_dict: dict, override_dict: dict) -> str: """Converts a library name to the actual instance of the library. This conversion is based off the library section definitions in the DSC. @@ -305,7 +303,7 @@ def _lib_to_instance( # 2/3. If the Library Class instance (INF) is defined in the [LibraryClasses.$(ARCH).$(MODULE_TYPE)] section, # and the library supports the module, then it will be used. - lookup = f'{arch}.{module}.{library_class_name}' + lookup = f"{arch}.{module}.{library_class_name}" if lookup in library_dict: library_instance = self._reduce_lib_instances(module, library_dict[lookup]) if library_instance is not None: @@ -313,7 +311,7 @@ def _lib_to_instance( # 4. If the Library Class instance (INF) is defined in the [LibraryClasses.common.$(MODULE_TYPE)] section, # and the library supports the module, then it will be used. - lookup = f'common.{module}.{library_class_name}' + lookup = f"common.{module}.{library_class_name}" if lookup in library_dict: library_instance = self._reduce_lib_instances(module, library_dict[lookup]) if library_instance is not None: @@ -321,7 +319,7 @@ def _lib_to_instance( # 5. If the Library Class instance (INF) is defined in the [LibraryClasses.$(ARCH)] section, # and the library supports the module, then it will be used. - lookup = f'{arch}.{library_class_name}' + lookup = f"{arch}.{library_class_name}" if lookup in library_dict: library_instance = self._reduce_lib_instances(module, library_dict[lookup]) if library_instance is not None: @@ -329,15 +327,15 @@ def _lib_to_instance( # 6. If the Library Class Instance (INF) is defined in the [LibraryClasses] section, # and the library supports the module, then it will be used. - lookup = f'common.{library_class_name}' + lookup = f"common.{library_class_name}" if lookup in library_dict: library_instance = self._reduce_lib_instances(module, library_dict[lookup]) if library_instance is not None: return library_instance - logging.debug(f'scoped library contents: {library_dict}') - logging.debug(f'override dictionary: {override_dict}') - e = f'Cannot find library class [{library_class_name}] for scope [{scope}] when evaluating {self.dsc}' + logging.debug(f"scoped library contents: {library_dict}") + logging.debug(f"override dictionary: {override_dict}") + e = f"Cannot find library class [{library_class_name}] for scope [{scope}] when evaluating {self.dsc}" logging.warning(e) return None @@ -378,16 +376,16 @@ def _get_null_lib_instances( arch, module = tuple(scope.split(".")) null_libs = [] - lookup = f'{arch}.{module}.null' + lookup = f"{arch}.{module}.null" null_libs.extend(library_dict.get(lookup, [])) - lookup = f'common.{module}.null' + lookup = f"common.{module}.null" null_libs.extend(library_dict.get(lookup, [])) - lookup = f'{arch}.null' + lookup = f"{arch}.null" null_libs.extend(library_dict.get(lookup, [])) - lookup = 'common.null' + lookup = "common.null" null_libs.extend(library_dict.get(lookup, [])) return null_libs diff --git a/edk2toollib/database/tables/package_table.py b/edk2toollib/database/tables/package_table.py index 884421f9..8d461e14 100644 --- a/edk2toollib/database/tables/package_table.py +++ b/edk2toollib/database/tables/package_table.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """A module to generate a table containing information about a package.""" + from pathlib import Path from typing import Any @@ -17,9 +18,12 @@ GIT_EXTENSION = ".git" DEC_EXTENSION = "*.dec" + + class PackageTable(TableGenerator): """A Table Generator that associates packages with their repositories.""" - def __init__(self, *args: Any, **kwargs: Any) -> 'PackageTable': + + def __init__(self, *args: Any, **kwargs: Any) -> "PackageTable": """Initializes the Repository Table Parser. Args: @@ -59,15 +63,13 @@ def parse(self, session: Session, pathobj: Edk2Path, id: str, env: dict) -> None break repository = all_repos.setdefault( - (containing_repo, repo_path), - Repository(name=containing_repo, path=repo_path) + (containing_repo, repo_path), Repository(name=containing_repo, path=repo_path) ) pkg_path = file.parent.relative_to(pathobj.WorkspacePath).as_posix() if (pkg_name, pkg_path) not in all_packages: package = all_packages.setdefault( - (pkg_name, pkg_path), - Package(name=pkg_name, path=pkg_path, repository=repository) + (pkg_name, pkg_path), Package(name=pkg_name, path=pkg_path, repository=repository) ) packages_to_add.append(package) session.add_all(packages_to_add) diff --git a/edk2toollib/database/tables/source_table.py b/edk2toollib/database/tables/source_table.py index fc4bb99a..885e343d 100644 --- a/edk2toollib/database/tables/source_table.py +++ b/edk2toollib/database/tables/source_table.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """A module to Parse all Source files and add them to the database.""" + import logging import re import time @@ -24,7 +25,8 @@ class SourceTable(TableGenerator): """A Table Generator that parses all c and h files in the workspace.""" - def __init__(self, *args: Any, **kwargs: Any) -> 'SourceTable': + + def __init__(self, *args: Any, **kwargs: Any) -> "SourceTable": """Initializes the Source Table Parser. Args: @@ -69,12 +71,13 @@ def parse(self, session: Session, pathobj: Edk2Path, id: str, env: dict) -> None logging.debug( f"{self.__class__.__name__}: Parsed {len(src_entries)} files; " - f"took {round(time.time() - start, 2)} seconds.") + f"took {round(time.time() - start, 2)} seconds." + ) def _parse_file(self, filename: Path) -> dict: """Parse a C file and return the results.""" license = "" - with open(filename, 'r', encoding='cp850') as f: + with open(filename, "r", encoding="cp850") as f: lines = f.readlines() for line in lines: match = re.search(r"SPDX-License-Identifier:\s*(.*)$", line) # TODO: This is not a standard format. @@ -94,7 +97,7 @@ def _parse_file(self, filename: Path) -> dict: path = self.pathobj.GetEdk2RelativePathFromAbsolutePath(filename.as_posix()) return Source( path=path, - license=license or 'Unknown', + license=license or "Unknown", total_lines=total_lines, code_lines=code_lines, comment_lines=comment_lines, diff --git a/edk2toollib/gitignore_parser.py b/edk2toollib/gitignore_parser.py index dd126365..2cbc8b50 100644 --- a/edk2toollib/gitignore_parser.py +++ b/edk2toollib/gitignore_parser.py @@ -2,6 +2,7 @@ # # SPDX-License-Identifier: BSD-2-Clause-Patent """Gitignore parser configured to work for edk2-pytool-library.""" + import collections import os import re @@ -53,7 +54,7 @@ def handle_negation(file_path: str, rules: list) -> bool: return False -def parse_gitignore_file(full_path: str, base_dir: Optional[str]=None) -> Callable: +def parse_gitignore_file(full_path: str, base_dir: Optional[str] = None) -> Callable: """Parse a gitignore file.""" if base_dir is None: base_dir = dirname(full_path) @@ -68,9 +69,8 @@ def parse_gitignore_lines(lines: list, full_path: str, base_dir: str) -> Callabl rules = [] for line in lines: counter += 1 - line = line.rstrip('\n') - rule = rule_from_pattern(line, base_path=Path(base_dir).resolve(), - source=(full_path, counter)) + line = line.rstrip("\n") + rule = rule_from_pattern(line, base_path=Path(base_dir).resolve(), source=(full_path, counter)) if rule: rules.append(rule) if not any(r.negation for r in rules): @@ -81,7 +81,7 @@ def parse_gitignore_lines(lines: list, full_path: str, base_dir: str) -> Callabl return lambda file_path: handle_negation(file_path, rules) -def rule_from_pattern(pattern: str, base_path: Optional[str]=None, source: Optional[str]=None) ->'IgnoreRule': +def rule_from_pattern(pattern: str, base_path: Optional[str] = None, source: Optional[str] = None) -> "IgnoreRule": """Generates an IgnoreRule object from a pattern. Take a .gitignore match pattern, such as "*.py[cod]" or "**/*.bak", @@ -92,60 +92,58 @@ def rule_from_pattern(pattern: str, base_path: Optional[str]=None, source: Optio is required for correct behavior. The base path should be absolute. """ if base_path and base_path != Path(base_path).resolve(): - raise ValueError('base_path must be absolute') + raise ValueError("base_path must be absolute") # Store the exact pattern for our repr and string functions orig_pattern = pattern # Early returns follow # Discard comments and separators - if pattern.strip() == '' or pattern[0] == '#': + if pattern.strip() == "" or pattern[0] == "#": return # Strip leading bang before examining double asterisks - if pattern[0] == '!': + if pattern[0] == "!": negation = True pattern = pattern[1:] else: negation = False # Multi-asterisks not surrounded by slashes (or at the start/end) should # be treated like single-asterisks. - pattern = re.sub(r'([^/])\*{2,}', r'\1*', pattern) - pattern = re.sub(r'\*{2,}([^/])', r'*\1', pattern) + pattern = re.sub(r"([^/])\*{2,}", r"\1*", pattern) + pattern = re.sub(r"\*{2,}([^/])", r"*\1", pattern) # Special-casing '/', which doesn't match any files or directories - if pattern.rstrip() == '/': + if pattern.rstrip() == "/": return - directory_only = pattern[-1] == '/' + directory_only = pattern[-1] == "/" # A slash is a sign that we're tied to the base_path of our rule # set. - anchored = '/' in pattern[:-1] - if pattern[0] == '/': + anchored = "/" in pattern[:-1] + if pattern[0] == "/": pattern = pattern[1:] - if pattern[0] == '*' and len(pattern) >= 2 and pattern[1] == '*': + if pattern[0] == "*" and len(pattern) >= 2 and pattern[1] == "*": pattern = pattern[2:] anchored = False - if pattern[0] == '/': + if pattern[0] == "/": pattern = pattern[1:] - if pattern[-1] == '/': + if pattern[-1] == "/": pattern = pattern[:-1] # patterns with leading hashes or exclamation marks are escaped with a # backslash in front, unescape it - if pattern[0] == '\\' and pattern[1] in ('#', '!'): + if pattern[0] == "\\" and pattern[1] in ("#", "!"): pattern = pattern[1:] # trailing spaces are ignored unless they are escaped with a backslash - i = len(pattern)-1 + i = len(pattern) - 1 striptrailingspaces = True - while i > 1 and pattern[i] == ' ': - if pattern[i-1] == '\\': - pattern = pattern[:i-1] + pattern[i:] + while i > 1 and pattern[i] == " ": + if pattern[i - 1] == "\\": + pattern = pattern[: i - 1] + pattern[i:] i = i - 1 striptrailingspaces = False else: if striptrailingspaces: pattern = pattern[:i] i = i - 1 - regex = fnmatch_pathname_to_regex( - pattern, directory_only, negation, anchored=bool(anchored) - ) + regex = fnmatch_pathname_to_regex(pattern, directory_only, negation, anchored=bool(anchored)) return IgnoreRule( pattern=orig_pattern, regex=regex, @@ -153,27 +151,31 @@ def rule_from_pattern(pattern: str, base_path: Optional[str]=None, source: Optio directory_only=directory_only, anchored=anchored, base_path=_normalize_path(base_path) if base_path else None, - source=source + source=source, ) IGNORE_RULE_FIELDS = [ - 'pattern', 'regex', # Basic values - 'negation', 'directory_only', 'anchored', # Behavior flags - 'base_path', # Meaningful for gitignore-style behavior - 'source' # (file, line) tuple for reporting + "pattern", + "regex", # Basic values + "negation", + "directory_only", + "anchored", # Behavior flags + "base_path", # Meaningful for gitignore-style behavior + "source", # (file, line) tuple for reporting ] -class IgnoreRule(collections.namedtuple('IgnoreRule_', IGNORE_RULE_FIELDS)): +class IgnoreRule(collections.namedtuple("IgnoreRule_", IGNORE_RULE_FIELDS)): """Class representing a single rule parsed from a .ignore file.""" + def __str__(self) -> str: """String representation (user friendly) of the rule.""" return self.pattern def __repr__(self) -> str: """String representation (developer friendly) of the rule.""" - return ''.join(['IgnoreRule(\'', self.pattern, '\')']) + return "".join(["IgnoreRule('", self.pattern, "')"]) def match(self, abs_path: str) -> bool: """Returns True or False if the path matches the rule.""" @@ -184,14 +186,14 @@ def match(self, abs_path: str) -> bool: rel_path = _normalize_path(abs_path).as_posix() # Path() strips the trailing following symbols on windows, so we need to # preserve it: ' ', '.' - if sys.platform.startswith('win'): - rel_path += ' ' * _count_trailing_symbol(' ', abs_path) - rel_path += '.' * _count_trailing_symbol('.', abs_path) + if sys.platform.startswith("win"): + rel_path += " " * _count_trailing_symbol(" ", abs_path) + rel_path += "." * _count_trailing_symbol(".", abs_path) # Path() strips the trailing slash, so we need to preserve it # in case of directory-only negation - if self.negation and isinstance(abs_path, str) and abs_path[-1] == '/': - rel_path += '/' - if rel_path.startswith('./'): + if self.negation and isinstance(abs_path, str) and abs_path[-1] == "/": + rel_path += "/" + if rel_path.startswith("./"): rel_path = rel_path[2:] if re.search(self.regex, rel_path): matched = True @@ -200,9 +202,7 @@ def match(self, abs_path: str) -> bool: # Frustratingly, python's fnmatch doesn't provide the FNM_PATHNAME # option that .gitignore's behavior depends on. -def fnmatch_pathname_to_regex( - pattern: str, directory_only: bool, negation: bool, anchored: bool = False -) -> str: +def fnmatch_pathname_to_regex(pattern: str, directory_only: bool, negation: bool, anchored: bool = False) -> str: """Implements fnmatch style-behavior, as though with FNM_PATHNAME flagged. WARNING: the path seperator will not match shell-style '*' and '.' wildcards. @@ -212,61 +212,62 @@ def fnmatch_pathname_to_regex( seps = [re.escape(os.sep)] if os.altsep is not None: seps.append(re.escape(os.altsep)) - seps_group = '[' + '|'.join(seps) + ']' - nonsep = r'[^{}]'.format('|'.join(seps)) + seps_group = "[" + "|".join(seps) + "]" + nonsep = r"[^{}]".format("|".join(seps)) res = [] while i < n: c = pattern[i] i += 1 - if c == '*': + if c == "*": try: - if pattern[i] == '*': + if pattern[i] == "*": i += 1 - if i < n and pattern[i] == '/': + if i < n and pattern[i] == "/": i += 1 - res.append(''.join(['(.*', seps_group, ')?'])) + res.append("".join(["(.*", seps_group, ")?"])) else: - res.append('.*') + res.append(".*") else: - res.append(''.join([nonsep, '*'])) + res.append("".join([nonsep, "*"])) except IndexError: - res.append(''.join([nonsep, '*'])) - elif c == '?': + res.append("".join([nonsep, "*"])) + elif c == "?": res.append(nonsep) - elif c == '/': + elif c == "/": res.append(seps_group) - elif c == '[': + elif c == "[": j = i - if j < n and pattern[j] == '!': + if j < n and pattern[j] == "!": j += 1 - if j < n and pattern[j] == ']': + if j < n and pattern[j] == "]": j += 1 - while j < n and pattern[j] != ']': + while j < n and pattern[j] != "]": j += 1 if j >= n: - res.append('\\[') + res.append("\\[") else: - stuff = pattern[i:j].replace('\\', '\\\\').replace('/', '') + stuff = pattern[i:j].replace("\\", "\\\\").replace("/", "") i = j + 1 - if stuff[0] == '!': - stuff = ''.join(['^', stuff[1:]]) - elif stuff[0] == '^': - stuff = ''.join('\\' + stuff) - res.append('[{}]'.format(stuff)) + if stuff[0] == "!": + stuff = "".join(["^", stuff[1:]]) + elif stuff[0] == "^": + stuff = "".join("\\" + stuff) + res.append("[{}]".format(stuff)) else: res.append(re.escape(c)) if anchored: - res.insert(0, '^') + res.insert(0, "^") else: res.insert(0, f"(^|{seps_group})") if not directory_only: - res.append('$') + res.append("$") elif directory_only and negation: - res.append('/$') + res.append("/$") else: - res.append('($|\\/)') - return ''.join(res) + res.append("($|\\/)") + return "".join(res) + def _normalize_path(path: Union[str, Path]) -> Path: """Normalize a path without resolving symlinks. diff --git a/edk2toollib/log/ansi_handler.py b/edk2toollib/log/ansi_handler.py index f63ddc0f..93c7b3dd 100644 --- a/edk2toollib/log/ansi_handler.py +++ b/edk2toollib/log/ansi_handler.py @@ -10,6 +10,7 @@ Will call into win32 commands as needed when needed """ + import logging import re from typing import IO, Callable, Optional @@ -20,6 +21,7 @@ # try to import windows types from winDLL import ctypes from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) from ctypes import wintypes except (AttributeError, ImportError): @@ -42,6 +44,7 @@ def winapi_test() -> None: # inspired by https://github.com/tartley/colorama/ class CONSOLE_SCREEN_BUFFER_INFO(Structure): """Object representing a console screen buffer.""" + COORD = wintypes._COORD """struct in wincon.h.""" _fields_ = [ @@ -54,17 +57,23 @@ class CONSOLE_SCREEN_BUFFER_INFO(Structure): def __str__(self) -> str: """String representation of the console screen buffer.""" - return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( - self.dwSize.Y, self.dwSize.X, - self.dwCursorPosition.Y, self.dwCursorPosition.X, + return "(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)" % ( + self.dwSize.Y, + self.dwSize.X, + self.dwCursorPosition.Y, + self.dwCursorPosition.X, self.wAttributes, - self.srWindow.Top, self.srWindow.Left, - self.srWindow.Bottom, self.srWindow.Right, - self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + self.srWindow.Top, + self.srWindow.Left, + self.srWindow.Bottom, + self.srWindow.Right, + self.dwMaximumWindowSize.Y, + self.dwMaximumWindowSize.X, ) class Win32Console(object): """A simple wrapper around the few methods calls to windows.""" + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute _SetConsoleTextAttribute.argtypes = [ @@ -85,24 +94,26 @@ class Win32Console(object): @staticmethod def _winapi_test(handle: Callable) -> bool: csbi = CONSOLE_SCREEN_BUFFER_INFO() - success = Win32Console._GetConsoleScreenBufferInfo( - handle, byref(csbi)) + success = Win32Console._GetConsoleScreenBufferInfo(handle, byref(csbi)) return bool(success) @staticmethod def winapi_test() -> Callable: """Returns the winapi_test.""" - return any(Win32Console._winapi_test(h) for h in - (Win32Console._GetStdHandle(Win32Console.STDOUT), - Win32Console._GetStdHandle(Win32Console.STDERR))) + return any( + Win32Console._winapi_test(h) + for h in ( + Win32Console._GetStdHandle(Win32Console.STDOUT), + Win32Console._GetStdHandle(Win32Console.STDERR), + ) + ) @staticmethod - def GetConsoleScreenBufferInfo(stream_id: int=STDOUT) -> CONSOLE_SCREEN_BUFFER_INFO: + def GetConsoleScreenBufferInfo(stream_id: int = STDOUT) -> CONSOLE_SCREEN_BUFFER_INFO: """Returns the console screen buffer info object.""" handle = Win32Console._GetStdHandle(stream_id) csbi = CONSOLE_SCREEN_BUFFER_INFO() - Win32Console._GetConsoleScreenBufferInfo( - handle, byref(csbi)) + Win32Console._GetConsoleScreenBufferInfo(handle, byref(csbi)) return csbi @staticmethod @@ -115,6 +126,7 @@ def SetConsoleTextAttribute(stream_id: int, attrs: int) -> bool: # from wincon.h class WinColor(object): """Enum representing Windows Console colors.""" + BLACK = 0 BLUE = 1 GREEN = 2 @@ -130,6 +142,7 @@ class WinColor(object): class AnsiColor(object): """Defines the different codes for the ansi colors.""" + BLACK = 30 RED = 31 GREEN = 32 @@ -167,7 +180,7 @@ class AnsiColor(object): BG_LIGHTWHITE_EX = 107 @classmethod - def __contains__(self: 'AnsiColor', item: str) -> bool: + def __contains__(self: "AnsiColor", item: str) -> bool: """Verifies we contain the color.""" if isinstance(item, str) and hasattr(self, item): return True @@ -180,23 +193,21 @@ def __contains__(self: 'AnsiColor', item: str) -> bool: class ColoredFormatter(logging.Formatter): """The formatter that outputs ANSI codes as needed.""" - AZURE_COLORS = { - 'CRITICAL': "section", - 'ERROR': "error" - } + + AZURE_COLORS = {"CRITICAL": "section", "ERROR": "error"} COLORS = { - 'WARNING': AnsiColor.YELLOW, - 'INFO': AnsiColor.CYAN, - 'DEBUG': AnsiColor.BLUE, - 'CRITICAL': AnsiColor.LIGHTWHITE_EX, - 'ERROR': AnsiColor.RED, + "WARNING": AnsiColor.YELLOW, + "INFO": AnsiColor.CYAN, + "DEBUG": AnsiColor.BLUE, + "CRITICAL": AnsiColor.LIGHTWHITE_EX, + "ERROR": AnsiColor.RED, "STATUS": AnsiColor.GREEN, "PROGRESS": AnsiColor.GREEN, - "SECTION": AnsiColor.CYAN + "SECTION": AnsiColor.CYAN, } - def __init__(self, msg: str="", use_azure: bool=False) -> 'ColoredFormatter': + def __init__(self, msg: str = "", use_azure: bool = False) -> "ColoredFormatter": """Inits the formatter.""" logging.Formatter.__init__(self, msg) self.use_azure = use_azure @@ -217,8 +228,7 @@ def format(self, record: logging.LogRecord) -> str: record.levelname = levelname_color if self.use_azure and levelname in ColoredFormatter.AZURE_COLORS: - levelname_color = "##[" + \ - ColoredFormatter.AZURE_COLORS[levelname] + "]" + levelname_color = "##[" + ColoredFormatter.AZURE_COLORS[levelname] + "]" record.levelname = levelname_color result = logging.Formatter.format(self, record) @@ -228,23 +238,24 @@ def format(self, record: logging.LogRecord) -> str: return result -def get_ansi_string(color: AnsiColor=AnsiColor.RESET) -> str: +def get_ansi_string(color: AnsiColor = AnsiColor.RESET) -> str: """Returns the string formatted ANSI command for the specific color.""" - CSI = '\033[' + CSI = "\033[" colors = AnsiColor() if color not in colors: color = AnsiColor.RESET - return CSI + str(color) + 'm' + return CSI + str(color) + "m" class ColoredStreamHandler(logging.StreamHandler): """Class for logging in Color..""" + # Control Sequence Introducer - ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') + ANSI_CSI_RE = re.compile("\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?") def __init__( - self, stream: Optional[IO]=None, strip: Optional[str]=None, convert: Optional[str]=None - ) -> 'ColoredStreamHandler': + self, stream: Optional[IO] = None, strip: Optional[str] = None, convert: Optional[str] = None + ) -> "ColoredStreamHandler": """Inits a Colored Stream Handler.""" logging.StreamHandler.__init__(self, stream) self.on_windows = GetHostInfo().os == "Windows" @@ -252,17 +263,16 @@ def __init__( # we may be using a terminal that doesn't support the WinAPI # (e.g. Cygwin Terminal). In this case it's up to the terminal # to support the ANSI codes. - self.conversion_supported = (self.on_windows and Win32Console.winapi_test()) + self.conversion_supported = self.on_windows and Win32Console.winapi_test() self.strip = False # should we strip ANSI sequences from our output? if strip is None: - strip = self.conversion_supported or ( - not self.stream.closed and not self.stream.isatty()) + strip = self.conversion_supported or (not self.stream.closed and not self.stream.isatty()) self.strip = strip # should we should convert ANSI sequences into win32 calls? if convert is None: - convert = (self.conversion_supported and not self.stream.closed and self.stream.isatty()) + convert = self.conversion_supported and not self.stream.closed and self.stream.isatty() self.convert = convert self.win32_calls = None @@ -272,8 +282,7 @@ def __init__( if self.on_windows: self.win32_calls = self.get_win32_calls() self._light = 0 - self._default = Win32Console.GetConsoleScreenBufferInfo( - Win32Console.STDOUT).wAttributes + self._default = Win32Console.GetConsoleScreenBufferInfo(Win32Console.STDOUT).wAttributes self.set_attrs(self._default) self._default_fore = self._fore self._default_back = self._back @@ -337,7 +346,7 @@ def get_win32_calls(self) -> dict: } return dict() - def set_foreground(self, fore: Optional[int]=None, light: bool=False, on_stderr: bool=False) -> None: + def set_foreground(self, fore: Optional[int] = None, light: bool = False, on_stderr: bool = False) -> None: """Does the win32 call to set the foreground.""" if fore is None: fore = self._default_fore @@ -349,7 +358,7 @@ def set_foreground(self, fore: Optional[int]=None, light: bool=False, on_stderr: self._light &= ~WinColor.BRIGHT self.set_console(on_stderr=on_stderr) - def set_background(self, back: Optional[int]=None, light: bool=False, on_stderr: bool=False) -> None: + def set_background(self, back: Optional[int] = None, light: bool = False, on_stderr: bool = False) -> None: """Does the win32 call to see the background.""" if back is None: back = self._default_back @@ -361,7 +370,7 @@ def set_background(self, back: Optional[int]=None, light: bool=False, on_stderr: self._light &= ~WinColor.BRIGHT_BACKGROUND self.set_console(on_stderr=on_stderr) - def set_console(self, attrs: Optional[int]=None, on_stderr: bool=False) -> None: + def set_console(self, attrs: Optional[int] = None, on_stderr: bool = False) -> None: """Does the win32 call to set the console text attribute.""" if attrs is None: attrs = self.get_attrs() @@ -392,14 +401,14 @@ def write_and_convert(self, text: str) -> None: cursor = 0 for match in self.ANSI_CSI_RE.finditer(text): start, end = match.span() - if (cursor < start): + if cursor < start: self.write_plain_text(text, cursor, start) self.convert_ansi(*match.groups()) cursor = end self.write_plain_text(text, cursor, len(text)) - def write_plain_text(self, text: str, start: Optional[int]=None, end: Optional[int]=None) -> None: + def write_plain_text(self, text: str, start: Optional[int] = None, end: Optional[int] = None) -> None: """Writes plain text to our stream.""" if start is None: self.stream.write(text) @@ -415,7 +424,7 @@ def convert_ansi(self, paramstring: str, command: str) -> None: def extract_params(self, command: str, paramstring: str) -> tuple: """Extracts the parameters in the ANSI command.""" - params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + params = tuple(int(p) for p in paramstring.split(";") if len(p) != 0) if len(params) == 0: params = (0,) @@ -423,7 +432,7 @@ def extract_params(self, command: str, paramstring: str) -> tuple: def call_win32(self, command: str, params: list) -> None: """Calls the win32 apis set_foreground and set_background.""" - if command == 'm': + if command == "m": for param in params: if param in self.win32_calls: func_args = self.win32_calls[param] diff --git a/edk2toollib/log/file_handler.py b/edk2toollib/log/file_handler.py index 92c2ed5a..5c300d5f 100644 --- a/edk2toollib/log/file_handler.py +++ b/edk2toollib/log/file_handler.py @@ -6,12 +6,14 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Module for handling basically logging to files.""" + import logging class FileHandler(logging.FileHandler): """Object for handling basic logging output to files.""" - def __init__(self, filename: str, mode: str='w+') -> 'FileHandler': + + def __init__(self, filename: str, mode: str = "w+") -> "FileHandler": """Init a file handler for the specified file.""" logging.FileHandler.__init__(self, filename, mode=mode) diff --git a/edk2toollib/log/junit_report_format.py b/edk2toollib/log/junit_report_format.py index 51f9e85f..c8eecb94 100644 --- a/edk2toollib/log/junit_report_format.py +++ b/edk2toollib/log/junit_report_format.py @@ -14,6 +14,7 @@ Used to support CI/CD and exporting test results for other tools. This does test report generation without being a test runner. """ + import time from typing import IO from xml.sax.saxutils import escape @@ -21,7 +22,8 @@ class JunitReportError(object): """Object representing a Test Error.""" - def __init__(self, type: str, msg: str) -> 'JunitReportError': + + def __init__(self, type: str, msg: str) -> "JunitReportError": """Init the type of error.""" self.Message = escape(msg.strip(), {'"': """}) self.Type = escape(type.strip(), {'"': """}) @@ -29,7 +31,8 @@ def __init__(self, type: str, msg: str) -> 'JunitReportError': class JunitReportFailure(object): """Object representing a Test Failure.""" - def __init__(self, type: str, msg: str) -> 'JunitReportFailure': + + def __init__(self, type: str, msg: str) -> "JunitReportFailure": """Init the type of Failure.""" self.Message = escape(msg.strip(), {'"': """}) self.Type = escape(type.strip(), {'"': """}) @@ -37,13 +40,14 @@ def __init__(self, type: str, msg: str) -> 'JunitReportFailure': class JunitReportTestCase(object): """Object representing a single test case.""" + NEW = 1 SKIPPED = 2 FAILED = 3 ERROR = 4 SUCCESS = 5 - def __init__(self, Name: str, ClassName: str) -> 'JunitReportTestCase': + def __init__(self, Name: str, ClassName: str) -> "JunitReportTestCase": """Init a Test case with it's name and class name.""" self.Name = escape(Name.strip(), {'"': """}) self.ClassName = escape(ClassName.strip(), {'"': """}) @@ -59,7 +63,7 @@ def __init__(self, Name: str, ClassName: str) -> 'JunitReportTestCase': def SetFailed(self, Msg: str, Type: str) -> None: """Sets internal state if the test failed.""" - if (self.Status != JunitReportTestCase.NEW): + if self.Status != JunitReportTestCase.NEW: raise Exception("Can't Set to failed. State must be in NEW") self.Time = time.time() - self._StartTime self.Status = JunitReportTestCase.FAILED @@ -67,7 +71,7 @@ def SetFailed(self, Msg: str, Type: str) -> None: def SetError(self, Msg: str, Type: str) -> None: """Set internal state if the test had an error.""" - if (self.Status != JunitReportTestCase.NEW): + if self.Status != JunitReportTestCase.NEW: raise Exception("Can't Set to error. State must be in NEW") self.Time = time.time() - self._StartTime self.Status = JunitReportTestCase.ERROR @@ -75,14 +79,14 @@ def SetError(self, Msg: str, Type: str) -> None: def SetSuccess(self) -> None: """Set internal state if the test passed.""" - if (self.Status != JunitReportTestCase.NEW): + if self.Status != JunitReportTestCase.NEW: raise Exception("Can't Set to success. State must be in NEW") self.Status = JunitReportTestCase.SUCCESS self.Time = time.time() - self._StartTime def SetSkipped(self) -> None: """Set internal state if the test was skipped.""" - if (self.Status != JunitReportTestCase.NEW): + if self.Status != JunitReportTestCase.NEW: raise Exception("Can't Set to skipped. State must be in NEW") self.Status = JunitReportTestCase.SKIPPED self.Time = time.time() - self._StartTime @@ -101,19 +105,21 @@ def Output(self, outstream: IO) -> None: if self.Status == JunitReportTestCase.SKIPPED: outstream.write('') outstream.write(self.StdOut) - outstream.write('') + outstream.write("") elif self.Status == JunitReportTestCase.FAILED: - outstream.write(''.format(self.FailureMsg.Message, - self.FailureMsg.Type)) + outstream.write( + ''.format(self.FailureMsg.Message, self.FailureMsg.Type) + ) elif self.Status == JunitReportTestCase.ERROR: outstream.write(''.format(self.ErrorMsg.Message, self.ErrorMsg.Type)) elif self.Status != JunitReportTestCase.SUCCESS: - raise Exception("Can't output a testcase {0}.{1} in invalid state {2}".format(self.ClassName, - self.Name, self.Status)) + raise Exception( + "Can't output a testcase {0}.{1} in invalid state {2}".format(self.ClassName, self.Name, self.Status) + ) - outstream.write('' + self.StdOut + '') - outstream.write('' + self.StdErr + '') - outstream.write('') + outstream.write("" + self.StdOut + "") + outstream.write("" + self.StdErr + "") + outstream.write("") class JunitReportTestSuite(object): @@ -121,7 +127,8 @@ class JunitReportTestSuite(object): Create new suites by using the JunitTestReport Object """ - def __init__(self, Name: str, Package: str, Id: id) -> 'JunitReportTestSuite': + + def __init__(self, Name: str, Package: str, Id: id) -> "JunitReportTestSuite": """Initialize a new test suite.""" self.Name = escape(Name.strip(), {'"': """}) self.Package = escape(Package.strip(), {'"': """}) @@ -147,21 +154,24 @@ def Output(self, outstream: IO) -> None: Tests = len(self.TestCases) for a in self.TestCases: - if (a.Status == JunitReportTestCase.FAILED): + if a.Status == JunitReportTestCase.FAILED: Failures += 1 - elif (a.Status == JunitReportTestCase.ERROR): + elif a.Status == JunitReportTestCase.ERROR: Errors += 1 - elif (a.Status == JunitReportTestCase.SKIPPED): + elif a.Status == JunitReportTestCase.SKIPPED: Skipped += 1 - outstream.write(''.format(self.TestId, self.Name, self.Package, - Errors, Tests, Failures, Skipped)) + outstream.write( + ''.format( + self.TestId, self.Name, self.Package, Errors, Tests, Failures, Skipped + ) + ) for a in self.TestCases: a.Output(outstream) - outstream.write('') + outstream.write("") class JunitTestReport(object): @@ -169,7 +179,8 @@ class JunitTestReport(object): Top level object test reporting. """ - def __init__(self) -> 'JunitTestReport': + + def __init__(self) -> "JunitTestReport": """Init an empty test report.""" self.TestSuites = [] @@ -187,10 +198,10 @@ def create_new_testsuite(self, name: str, package: str) -> JunitReportTestSuite: def Output(self, filepath: str) -> None: """Write report to file.""" f = open(filepath, "w") - f.write('') + f.write("") f.write('') - f.write('') + f.write("") for a in self.TestSuites: a.Output(f) - f.write('') + f.write("") f.close() diff --git a/edk2toollib/log/string_handler.py b/edk2toollib/log/string_handler.py index 7c3b2aa1..a4f39412 100644 --- a/edk2toollib/log/string_handler.py +++ b/edk2toollib/log/string_handler.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Module for handling basic logging by streaming into StringIO.""" + import io import logging from logging import LogRecord @@ -13,9 +14,10 @@ class StringStreamHandler(logging.StreamHandler): """Class for logging via StringIO.""" - terminator = '\n' - def __init__(self) -> 'StringStreamHandler': + terminator = "\n" + + def __init__(self) -> "StringStreamHandler": """Init a StringStreamHandler.""" logging.Handler.__init__(self) self.stream = io.StringIO() @@ -37,7 +39,7 @@ def handle(self, record: LogRecord) -> bool: self.release() return rv - def readlines(self, hint: int=-1) -> list[str]: + def readlines(self, hint: int = -1) -> list[str]: """Reads lines from stream and returns them.""" return self.stream.readlines(hint) diff --git a/edk2toollib/os/uefivariablesupport.py b/edk2toollib/os/uefivariablesupport.py index de14bedc..3f087dbd 100644 --- a/edk2toollib/os/uefivariablesupport.py +++ b/edk2toollib/os/uefivariablesupport.py @@ -25,7 +25,7 @@ import uuid from ctypes import create_string_buffer -if os.name == 'nt': +if os.name == "nt": from ctypes import WinError, c_int, c_void_p, c_wchar_p, pointer, windll from ctypes.wintypes import DWORD @@ -44,29 +44,24 @@ class UefiVariable(object): GetUefiAllVarNames - Get all Uefi variables SetUefiVar - Set (or delete) a single Uefi variable. """ - ERROR_ENVVAR_NOT_FOUND = 0xcb + + ERROR_ENVVAR_NOT_FOUND = 0xCB def __init__(self) -> None: """Initialize Class.""" - if os.name == 'nt': + if os.name == "nt": # enable required SeSystemEnvironmentPrivilege privilege - privilege = win32security.LookupPrivilegeValue( - None, "SeSystemEnvironmentPrivilege" - ) + privilege = win32security.LookupPrivilegeValue(None, "SeSystemEnvironmentPrivilege") token = win32security.OpenProcessToken( win32process.GetCurrentProcess(), win32security.TOKEN_READ | win32security.TOKEN_ADJUST_PRIVILEGES, ) - win32security.AdjustTokenPrivileges( - token, False, [(privilege, win32security.SE_PRIVILEGE_ENABLED)] - ) + win32security.AdjustTokenPrivileges(token, False, [(privilege, win32security.SE_PRIVILEGE_ENABLED)]) win32api.CloseHandle(token) # import firmware variable API try: - self._GetFirmwareEnvironmentVariable = ( - windll.kernel32.GetFirmwareEnvironmentVariableW - ) + self._GetFirmwareEnvironmentVariable = windll.kernel32.GetFirmwareEnvironmentVariableW self._GetFirmwareEnvironmentVariable.restype = c_int self._GetFirmwareEnvironmentVariable.argtypes = [ c_wchar_p, @@ -74,18 +69,10 @@ def __init__(self) -> None: c_void_p, c_int, ] - self._EnumerateFirmwareEnvironmentVariable = ( - windll.ntdll.NtEnumerateSystemEnvironmentValuesEx - ) + self._EnumerateFirmwareEnvironmentVariable = windll.ntdll.NtEnumerateSystemEnvironmentValuesEx self._EnumerateFirmwareEnvironmentVariable.restype = c_int - self._EnumerateFirmwareEnvironmentVariable.argtypes = [ - c_int, - c_void_p, - c_void_p - ] - self._SetFirmwareEnvironmentVariable = ( - windll.kernel32.SetFirmwareEnvironmentVariableW - ) + self._EnumerateFirmwareEnvironmentVariable.argtypes = [c_int, c_void_p, c_void_p] + self._SetFirmwareEnvironmentVariable = windll.kernel32.SetFirmwareEnvironmentVariableW self._SetFirmwareEnvironmentVariable.restype = c_int self._SetFirmwareEnvironmentVariable.argtypes = [ c_wchar_p, @@ -93,9 +80,7 @@ def __init__(self) -> None: c_void_p, c_int, ] - self._SetFirmwareEnvironmentVariableEx = ( - windll.kernel32.SetFirmwareEnvironmentVariableExW - ) + self._SetFirmwareEnvironmentVariableEx = windll.kernel32.SetFirmwareEnvironmentVariableExW self._SetFirmwareEnvironmentVariableEx.restype = c_int self._SetFirmwareEnvironmentVariableEx.argtypes = [ c_wchar_p, @@ -105,9 +90,7 @@ def __init__(self) -> None: c_int, ] except Exception: - logging.warn( - "Collecting windll Variable functions encountered an error." - ) + logging.warn("Collecting windll Variable functions encountered an error.") else: pass @@ -125,24 +108,17 @@ def GetUefiVar(self, name: str, guid: str) -> tuple[int, str]: length = 0 # Remove null termination on the name, if it exists. - name = name.rstrip('\x00') + name = name.rstrip("\x00") - if os.name == 'nt': + if os.name == "nt": efi_var = create_string_buffer(EFI_VAR_MAX_BUFFER_SIZE) if self._GetFirmwareEnvironmentVariable is not None: - logging.info( - "calling GetFirmwareEnvironmentVariable( name='%s', GUID='%s' ).." - % (name, "{%s}" % guid) - ) - length = self._GetFirmwareEnvironmentVariable( - name, "{%s}" % guid, efi_var, EFI_VAR_MAX_BUFFER_SIZE - ) + logging.info("calling GetFirmwareEnvironmentVariable( name='%s', GUID='%s' ).." % (name, "{%s}" % guid)) + length = self._GetFirmwareEnvironmentVariable(name, "{%s}" % guid, efi_var, EFI_VAR_MAX_BUFFER_SIZE) if (0 == length) or (efi_var is None): err = windll.kernel32.GetLastError() if err != 0 and err != UefiVariable.ERROR_ENVVAR_NOT_FOUND: - logging.error( - "GetFirmwareEnvironmentVariable[Ex] failed (GetLastError = 0x%x)" % err - ) + logging.error("GetFirmwareEnvironmentVariable[Ex] failed (GetLastError = 0x%x)" % err) logging.error(WinError()) if efi_var is None: return (err, None) @@ -150,14 +126,14 @@ def GetUefiVar(self, name: str, guid: str) -> tuple[int, str]: else: # the variable name is VariableName-Guid - path = '/sys/firmware/efi/efivars/' + name + '-%s' % guid + path = "/sys/firmware/efi/efivars/" + name + "-%s" % guid if not os.path.exists(path): err = UefiVariable.ERROR_ENVVAR_NOT_FOUND return (err, None) efi_var = create_string_buffer(EFI_VAR_MAX_BUFFER_SIZE) - with open(path, 'rb') as fd: + with open(path, "rb") as fd: efi_var = fd.read() length = len(efi_var) @@ -180,7 +156,7 @@ def GetUefiAllVarNames(self) -> tuple[int, bytes]: } """ status = 0 - if os.name == 'nt': + if os.name == "nt": # From NTSTATUS definition: # (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55) STATUS_BUFFER_TOO_SMALL = 0xC0000023 @@ -189,29 +165,25 @@ def GetUefiAllVarNames(self) -> tuple[int, bytes]: length = DWORD(0) efi_var_names = create_string_buffer(length.value) if self._EnumerateFirmwareEnvironmentVariable is not None: - logging.info( - "calling _EnumerateFirmwareEnvironmentVariable to get size.." - ) + logging.info("calling _EnumerateFirmwareEnvironmentVariable to get size..") status = self._EnumerateFirmwareEnvironmentVariable( - VARIABLE_INFORMATION_NAMES, efi_var_names, pointer(length)) + VARIABLE_INFORMATION_NAMES, efi_var_names, pointer(length) + ) # Only inspect the lower 32 bits. - status = (0xFFFFFFFF & status) + status = 0xFFFFFFFF & status if status == STATUS_BUFFER_TOO_SMALL: - logging.info( - "calling _EnumerateFirmwareEnvironmentVariable again to get data..") + logging.info("calling _EnumerateFirmwareEnvironmentVariable again to get data..") efi_var_names = create_string_buffer(length.value) status = self._EnumerateFirmwareEnvironmentVariable( - VARIABLE_INFORMATION_NAMES, efi_var_names, pointer( - length)) - if (0 != status): - logging.error( - "EnumerateFirmwareEnvironmentVariable failed (GetLastError = 0x%x)" % status - ) + VARIABLE_INFORMATION_NAMES, efi_var_names, pointer(length) + ) + if 0 != status: + logging.error("EnumerateFirmwareEnvironmentVariable failed (GetLastError = 0x%x)" % status) return (status, None) return (status, efi_var_names) else: # implementation borrowed from https://github.com/awslabs/python-uefivars/blob/main/pyuefivars/efivarfs.py - path = '/sys/firmware/efi/efivars' + path = "/sys/firmware/efi/efivars" if not os.path.exists(path): status = UefiVariable.ERROR_ENVVAR_NOT_FOUND return (status, None) @@ -222,39 +194,38 @@ def GetUefiAllVarNames(self) -> tuple[int, bytes]: length = 0 offset = 0 for var in vars: - split_string = var.split('-') - name = '-'.join(split_string[:-5]) - name = name.encode('utf-16-le') + split_string = var.split("-") + name = "-".join(split_string[:-5]) + name = name.encode("utf-16-le") name_len = len(name) - length += (4 + 16 + name_len) + length += 4 + 16 + name_len efi_var_names = create_string_buffer(length) for var in vars: # efivarfs stores vars as NAME-GUID - split_string = var.split('-') + split_string = var.split("-") try: # GUID is last 5 elements of split_string - guid = uuid.UUID('-'.join(split_string[-5:])).bytes_le + guid = uuid.UUID("-".join(split_string[-5:])).bytes_le except ValueError: raise Exception(f'Could not parse "{var}"') # the other part is the name - name = '-'.join(split_string[:-5]) - name = name.encode('utf-16-le') + name = "-".join(split_string[:-5]) + name = name.encode("utf-16-le") name_len = len(name) # NextEntryOffset - struct.pack_into(' Optional[int]: """Returns associated command code. @@ -488,6 +490,7 @@ class ResponseCode(object): Allows alternativing between response codes and response strings. """ + @staticmethod def get_simple_string(rc_code: int) -> Optional[str]: """Returns associated response string. @@ -539,76 +542,76 @@ def get_simple_string(rc_code: int) -> Optional[str]: def parse_code(rc_code: int) -> tuple: """Returns a Tuple representing the parsed response code.""" generic_errors = { - 0x000: 'TPM_RC_INITIALIZE', - 0x001: 'TPM_RC_FAILURE', - 0x003: 'TPM_RC_SEQUENCE', - 0x00B: 'TPM_RC_PRIVATE', - 0x019: 'TPM_RC_HMAC', - 0x020: 'TPM_RC_DISABLED', - 0x021: 'TPM_RC_EXCLUSIVE', - 0x024: 'TPM_RC_AUTH_TYPE', - 0x025: 'TPM_RC_AUTH_MISSING', - 0x026: 'TPM_RC_POLICY', - 0x027: 'TPM_RC_PCR', - 0x028: 'TPM_RC_PCR_CHANGED', - 0x02D: 'TPM_RC_UPGRADE', - 0x02E: 'TPM_RC_TOO_MANY_CONTEXTS', - 0x02F: 'TPM_RC_AUTH_UNAVAILABLE', - 0x030: 'TPM_RC_REBOOT', - 0x031: 'TPM_RC_UNBALANCED', - 0x042: 'TPM_RC_COMMAND_SIZE', - 0x043: 'TPM_RC_COMMAND_CODE', - 0x044: 'TPM_RC_AUTHSIZE', - 0x045: 'TPM_RC_AUTH_CONTEXT', - 0x046: 'TPM_RC_NV_RANGE', - 0x047: 'TPM_RC_NV_SIZE', - 0x048: 'TPM_RC_NV_LOCKED', - 0x049: 'TPM_RC_NV_AUTHORIZATION', - 0x04A: 'TPM_RC_NV_UNINITIALIZED', - 0x04B: 'TPM_RC_NV_SPACE', - 0x04C: 'TPM_RC_NV_DEFINED', - 0x050: 'TPM_RC_BAD_CONTEXT', - 0x051: 'TPM_RC_CPHASH', - 0x052: 'TPM_RC_PARENT', - 0x053: 'TPM_RC_NEEDS_TEST', - 0x054: 'TPM_RC_NO_RESULT', - 0x055: 'TPM_RC_SENSITIVE', + 0x000: "TPM_RC_INITIALIZE", + 0x001: "TPM_RC_FAILURE", + 0x003: "TPM_RC_SEQUENCE", + 0x00B: "TPM_RC_PRIVATE", + 0x019: "TPM_RC_HMAC", + 0x020: "TPM_RC_DISABLED", + 0x021: "TPM_RC_EXCLUSIVE", + 0x024: "TPM_RC_AUTH_TYPE", + 0x025: "TPM_RC_AUTH_MISSING", + 0x026: "TPM_RC_POLICY", + 0x027: "TPM_RC_PCR", + 0x028: "TPM_RC_PCR_CHANGED", + 0x02D: "TPM_RC_UPGRADE", + 0x02E: "TPM_RC_TOO_MANY_CONTEXTS", + 0x02F: "TPM_RC_AUTH_UNAVAILABLE", + 0x030: "TPM_RC_REBOOT", + 0x031: "TPM_RC_UNBALANCED", + 0x042: "TPM_RC_COMMAND_SIZE", + 0x043: "TPM_RC_COMMAND_CODE", + 0x044: "TPM_RC_AUTHSIZE", + 0x045: "TPM_RC_AUTH_CONTEXT", + 0x046: "TPM_RC_NV_RANGE", + 0x047: "TPM_RC_NV_SIZE", + 0x048: "TPM_RC_NV_LOCKED", + 0x049: "TPM_RC_NV_AUTHORIZATION", + 0x04A: "TPM_RC_NV_UNINITIALIZED", + 0x04B: "TPM_RC_NV_SPACE", + 0x04C: "TPM_RC_NV_DEFINED", + 0x050: "TPM_RC_BAD_CONTEXT", + 0x051: "TPM_RC_CPHASH", + 0x052: "TPM_RC_PARENT", + 0x053: "TPM_RC_NEEDS_TEST", + 0x054: "TPM_RC_NO_RESULT", + 0x055: "TPM_RC_SENSITIVE", } handle_errors = { - 0x001: 'TPM_RC_ASYMMETRIC', - 0x002: 'TPM_RC_ATTRIBUTES', - 0x003: 'TPM_RC_HASH', - 0x004: 'TPM_RC_VALUE', - 0x005: 'TPM_RC_HIERARCHY', - 0x007: 'TPM_RC_KEY_SIZE', - 0x008: 'TPM_RC_MGF', - 0x009: 'TPM_RC_MODE', - 0x00A: 'TPM_RC_TYPE', - 0x00B: 'TPM_RC_HANDLE', - 0x00C: 'TPM_RC_KDF', - 0x00D: 'TPM_RC_RANGE', - 0x00E: 'TPM_RC_AUTH_FAIL', - 0x00F: 'TPM_RC_NONCE', - 0x010: 'TPM_RC_PP', - 0x012: 'TPM_RC_SCHEME', - 0x015: 'TPM_RC_SIZE', - 0x016: 'TPM_RC_SYMMETRIC', - 0x017: 'TPM_RC_TAG', - 0x018: 'TPM_RC_SELECTOR', - 0x01A: 'TPM_RC_INSUFFICIENT', - 0x01B: 'TPM_RC_SIGNATURE', - 0x01C: 'TPM_RC_KEY', - 0x01D: 'TPM_RC_POLICY_FAIL', - 0x01F: 'TPM_RC_INTEGRITY', - 0x020: 'TPM_RC_TICKET', - 0x021: 'TPM_RC_RESERVED_BITS', - 0x022: 'TPM_RC_BAD_AUTH', - 0x023: 'TPM_RC_EXPIRED', - 0x024: 'TPM_RC_POLICY_CC', - 0x025: 'TPM_RC_BINDING', - 0x026: 'TPM_RC_CURVE', - 0x027: 'TPM_RC_ECC_POINT', + 0x001: "TPM_RC_ASYMMETRIC", + 0x002: "TPM_RC_ATTRIBUTES", + 0x003: "TPM_RC_HASH", + 0x004: "TPM_RC_VALUE", + 0x005: "TPM_RC_HIERARCHY", + 0x007: "TPM_RC_KEY_SIZE", + 0x008: "TPM_RC_MGF", + 0x009: "TPM_RC_MODE", + 0x00A: "TPM_RC_TYPE", + 0x00B: "TPM_RC_HANDLE", + 0x00C: "TPM_RC_KDF", + 0x00D: "TPM_RC_RANGE", + 0x00E: "TPM_RC_AUTH_FAIL", + 0x00F: "TPM_RC_NONCE", + 0x010: "TPM_RC_PP", + 0x012: "TPM_RC_SCHEME", + 0x015: "TPM_RC_SIZE", + 0x016: "TPM_RC_SYMMETRIC", + 0x017: "TPM_RC_TAG", + 0x018: "TPM_RC_SELECTOR", + 0x01A: "TPM_RC_INSUFFICIENT", + 0x01B: "TPM_RC_SIGNATURE", + 0x01C: "TPM_RC_KEY", + 0x01D: "TPM_RC_POLICY_FAIL", + 0x01F: "TPM_RC_INTEGRITY", + 0x020: "TPM_RC_TICKET", + 0x021: "TPM_RC_RESERVED_BITS", + 0x022: "TPM_RC_BAD_AUTH", + 0x023: "TPM_RC_EXPIRED", + 0x024: "TPM_RC_POLICY_CC", + 0x025: "TPM_RC_BINDING", + 0x026: "TPM_RC_CURVE", + 0x027: "TPM_RC_ECC_POINT", } warnings = { @@ -644,43 +647,43 @@ def parse_code(rc_code: int) -> tuple: # Check for TPM_RC_SUCCESS. if rc_code == 0x00: - return ('Success', 'None', 0, 'TPM_RC_SUCCESS', 'NA') + return ("Success", "None", 0, "TPM_RC_SUCCESS", "NA") # Check for TPM 1.2 response. if not (rc_code & (0b11 << 7)): - return ('Tpm1.2 Response', 'None', 0, 0, 'NA') + return ("Tpm1.2 Response", "None", 0, 0, "NA") # Check bit 7. if not (rc_code & (1 << 7)): # Check bit 10. - if (rc_code & (1 << 10)): - return ('Vendor Defined Code', 'None', 0, 0, 'NA') + if rc_code & (1 << 10): + return ("Vendor Defined Code", "None", 0, 0, "NA") # At this point the code will be in [6:0]... code = rc_code & 0b1111111 # Check bit 11. - if (rc_code & (1 << 11)): - return ('Warning', 'None', 0, warnings[code], 'NA') # TODO: Complete this. + if rc_code & (1 << 11): + return ("Warning", "None", 0, warnings[code], "NA") # TODO: Complete this. else: - return ('Error', 'None', 0, code, generic_errors[code]) + return ("Error", "None", 0, code, generic_errors[code]) # At this point the code will always be in [5:0]... code = rc_code & 0b111111 # Check bit 6. - if (rc_code & (1 << 6)): + if rc_code & (1 << 6): number = (rc_code >> 8) & 0b1111 - return ('Error', 'Parameter', number, code, 'NA') # TODO: Complete this. + return ("Error", "Parameter", number, code, "NA") # TODO: Complete this. # At this point the nubmer will always be in [10:8]... number = (rc_code >> 8) & 0b111 # Check bit 11. if not (rc_code & (1 << 11)): - return ('Error', 'Handle', number, code, handle_errors[code]) # TODO: Complete this. + return ("Error", "Handle", number, code, handle_errors[code]) # TODO: Complete this. else: - return ('Error', 'Session', number, code, 'NA') # TODO: Complete this. + return ("Error", "Session", number, code, "NA") # TODO: Complete this. raise ValueError("Code '0x%x' could not be parsed!" % rc_code) return None diff --git a/edk2toollib/tpm/tpm2_policy_calc.py b/edk2toollib/tpm/tpm2_policy_calc.py index c422c1bf..580efc3a 100644 --- a/edk2toollib/tpm/tpm2_policy_calc.py +++ b/edk2toollib/tpm/tpm2_policy_calc.py @@ -30,7 +30,8 @@ class PolicyHasher(object): """An object used to hash TPM 2.0 policies with a specified hash.""" - def __init__(self, hash_type: str) -> 'PolicyHasher': + + def __init__(self, hash_type: str) -> "PolicyHasher": """Init the hasher with the specified hash. Args: @@ -39,14 +40,11 @@ def __init__(self, hash_type: str) -> 'PolicyHasher': Raises: (ValueError): Invalid hash type """ - if hash_type not in ['sha256', 'sha384']: + if hash_type not in ["sha256", "sha384"]: raise ValueError("Invalid hash type '%s'!" % hash_type) self.hash_type = hash_type - self.hash_size = { - 'sha256': 32, - 'sha384': 48 - }[hash_type] + self.hash_size = {"sha256": 32, "sha384": 48}[hash_type] def get_size(self) -> int: """Returns the size of the hash.""" @@ -55,7 +53,7 @@ def get_size(self) -> int: def hash(self, data: str) -> bytes: """Hashes the data using the specified type.""" hash_obj = None - if self.hash_type == 'sha256': + if self.hash_type == "sha256": hash_obj = hashlib.sha256() else: hash_obj = hashlib.sha384() @@ -65,20 +63,21 @@ def hash(self, data: str) -> bytes: return hash_obj.digest() -class PolicyCalculator(object): # noqa - def __init__(self, primitive_dict, policy_tree): # noqa +class PolicyCalculator(object): # noqa + def __init__(self, primitive_dict, policy_tree): # noqa # For now, we'll leave this pretty sparse. # We should have WAY more testing for this stuff. self.primitive_dict = primitive_dict self.policy_tree = policy_tree - def generate_digest(self, digest_type): # noqa + def generate_digest(self, digest_type): # noqa pass class PolicyTreeOr(object): """Object representing an OR junction in a policy tree.""" - def __init__(self, components: Union['PolicyTreeAnd', 'PolicyTreeOr', 'PolicyTreeSolo']) -> 'PolicyTreeOr': + + def __init__(self, components: Union["PolicyTreeAnd", "PolicyTreeOr", "PolicyTreeSolo"]) -> "PolicyTreeOr": """Inits the policy tree junction with a list of connected components. Args: @@ -96,7 +95,7 @@ def __init__(self, components: Union['PolicyTreeAnd', 'PolicyTreeOr', 'PolicyTre def get_type(self) -> str: """Returns the type of junction.""" - return 'or' + return "or" def validate(self) -> bool: """Validates all components have the correct attributes.""" @@ -104,51 +103,52 @@ def validate(self) -> bool: for component in self.components: # All components must be convertible into a policy. - if not hasattr(component, 'get_policy'): + if not hasattr(component, "get_policy"): result = False # All components must also be valid. - if not hasattr(component, 'validate') or not component.validate(): + if not hasattr(component, "validate") or not component.validate(): result = False return result - def get_policy_buffer(self, hash_obj: Union['PolicyTreeAnd', 'PolicyTreeOr', 'PolicyTreeSolo']) -> bytes: + def get_policy_buffer(self, hash_obj: Union["PolicyTreeAnd", "PolicyTreeOr", "PolicyTreeSolo"]) -> bytes: """Creates and returns a buffer representing the policy.""" - concat_policy_buffer = b'\x00' * hash_obj.get_size() + concat_policy_buffer = b"\x00" * hash_obj.get_size() concat_policy_buffer += struct.pack(">L", t2d.TPM_CC_PolicyOR) - concat_policy_buffer += b''.join([component.get_policy(hash_obj) for component in self.components]) + concat_policy_buffer += b"".join([component.get_policy(hash_obj) for component in self.components]) return concat_policy_buffer - def get_policy(self, hash_obj: Union['PolicyTreeAnd', 'PolicyTreeOr', 'PolicyTreeSolo']) -> int: + def get_policy(self, hash_obj: Union["PolicyTreeAnd", "PolicyTreeOr", "PolicyTreeSolo"]) -> int: """Returns a hashed policy buffer.""" return hash_obj.hash(self.get_policy_buffer(hash_obj)) class PolicyTreeAnd(object): """Object representing an AND junction in a policy tree.""" - def __init__(self, components: list[Union['PolicyTreeAnd', 'PolicyTreeOr', 'PolicyTreeSolo']]) -> 'PolicyTreeAnd': + + def __init__(self, components: list[Union["PolicyTreeAnd", "PolicyTreeOr", "PolicyTreeSolo"]]) -> "PolicyTreeAnd": """Inits the policy tree junction with a list of connected components.""" # ANDs must only be composed of primitives. For simplicity, I guess. # Honestly, this has spiralled out of control, but something is better than nothing. for component in components: - if not hasattr(component, 'get_buffer_for_digest'): + if not hasattr(component, "get_buffer_for_digest"): raise ValueError("AND junctions must consist of primitives!") self.components = components def get_type(self) -> str: """Returns the type of junction.""" - return 'and' + return "and" def validate(self) -> bool: """Validate.""" # Not sure why don't validate here instead of in the init? return True - def get_policy(self, hash_obj: Union['PolicyTreeAnd', 'PolicyTreeOr', 'PolicyTreeSolo']) -> bytes: + def get_policy(self, hash_obj: Union["PolicyTreeAnd", "PolicyTreeOr", "PolicyTreeSolo"]) -> bytes: """Returns a hashed policy buffer.""" - current_digest = b'\x00' * hash_obj.get_size() + current_digest = b"\x00" * hash_obj.get_size() for component in self.components: current_digest = hash_obj.hash(current_digest + component.get_buffer_for_digest()) return current_digest @@ -157,27 +157,27 @@ def get_policy(self, hash_obj: Union['PolicyTreeAnd', 'PolicyTreeOr', 'PolicyTre class PolicyTreeSolo(object): """This object should only be used to put a single policy claim under an OR.""" - def __init__(self, policy_obj: Union['PolicyTreeAnd', 'PolicyTreeOr', 'PolicyTreeSolo']) -> 'PolicyTreeSolo': + def __init__(self, policy_obj: Union["PolicyTreeAnd", "PolicyTreeOr", "PolicyTreeSolo"]) -> "PolicyTreeSolo": """Inits the policy tree junction.""" - if not hasattr(policy_obj, 'get_buffer_for_digest'): + if not hasattr(policy_obj, "get_buffer_for_digest"): raise ValueError("Supplied policy object is missing required functionality!") self.policy_obj = policy_obj def get_type(self) -> str: """Returns the type of junction.""" - return 'solo' + return "solo" def validate(self) -> bool: """Validate.""" # Not sure why don't validate here instead of in the init? return True - def get_policy_buffer(self, hash_obj: Union['PolicyTreeAnd', 'PolicyTreeOr', 'PolicyTreeSolo']) -> bytes: + def get_policy_buffer(self, hash_obj: Union["PolicyTreeAnd", "PolicyTreeOr", "PolicyTreeSolo"]) -> bytes: """Creates and returns a buffer representing the policy.""" - return (b'\x00' * hash_obj.get_size()) + self.policy_obj.get_buffer_for_digest() + return (b"\x00" * hash_obj.get_size()) + self.policy_obj.get_buffer_for_digest() - def get_policy(self, hash_obj: Union['PolicyTreeAnd', 'PolicyTreeOr']) -> int: + def get_policy(self, hash_obj: Union["PolicyTreeAnd", "PolicyTreeOr"]) -> int: """Returns a hashed policy buffer.""" return hash_obj.hash(self.get_policy_buffer(hash_obj)) @@ -193,7 +193,8 @@ def get_policy(self, hash_obj: Union['PolicyTreeAnd', 'PolicyTreeOr']) -> int: class PolicyLocality(object): """Policy Primitive to describe a single assertion to create complex assertions.""" - def __init__(self, localities: list[int]) -> 'PolicyLocality': + + def __init__(self, localities: list[int]) -> "PolicyLocality": """Init with the requested localities.""" # Update the bitfield with the requested localities. if localities is not None: @@ -245,7 +246,8 @@ def get_buffer_for_digest(self) -> str: class PolicyCommandCode(object): """Policy Primitive to describe a Command code.""" - def __init__(self, command_code_string: Optional[str]=None) -> 'PolicyCommandCode': + + def __init__(self, command_code_string: Optional[str] = None) -> "PolicyCommandCode": """Init with the requested command code string.""" # Check to make sure that a command_code can be found. str_command_code_string = str(command_code_string) @@ -265,5 +267,8 @@ def get_buffer_for_digest(self) -> str: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ # NOTE: We force big-endian to match the marshalling in the TPM. - return struct.pack(">LL", t2d.CommandCode.get_code('TPM_CC_PolicyCommandCode'), - t2d.CommandCode.get_code(self.command_code_string)) + return struct.pack( + ">LL", + t2d.CommandCode.get_code("TPM_CC_PolicyCommandCode"), + t2d.CommandCode.get_code(self.command_code_string), + ) diff --git a/edk2toollib/tpm/tpm2_simulator.py b/edk2toollib/tpm/tpm2_simulator.py index b9541811..3f494e54 100644 --- a/edk2toollib/tpm/tpm2_simulator.py +++ b/edk2toollib/tpm/tpm2_simulator.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Module that contains transportation layer classes for interacting with the TPM 2.0 simulator.""" + import socket import struct @@ -13,36 +14,37 @@ import edk2toollib.tpm.tpm2_stream as t2s PLAT_COMMANDS = { - 'TPM_SIGNAL_POWER_ON': 1, - 'TPM_SIGNAL_POWER_OFF': 2, - 'TPM_SIGNAL_PHYS_PRES_ON': 3, - 'TPM_SIGNAL_PHYS_PRES_OFF': 4, - 'TPM_SIGNAL_HASH_START': 5, - 'TPM_SIGNAL_HASH_DATA': 6, + "TPM_SIGNAL_POWER_ON": 1, + "TPM_SIGNAL_POWER_OFF": 2, + "TPM_SIGNAL_PHYS_PRES_ON": 3, + "TPM_SIGNAL_PHYS_PRES_OFF": 4, + "TPM_SIGNAL_HASH_START": 5, + "TPM_SIGNAL_HASH_DATA": 6, # {UINT32 BufferSize, BYTE[BufferSize] Buffer} - 'TPM_SIGNAL_HASH_END': 7, - 'TPM_SEND_COMMAND': 8, + "TPM_SIGNAL_HASH_END": 7, + "TPM_SEND_COMMAND": 8, # {BYTE Locality, UINT32 InBufferSize, BYTE[InBufferSize] InBuffer} -> # {UINT32 OutBufferSize, BYTE[OutBufferSize] OutBuffer} - 'TPM_SIGNAL_CANCEL_ON': 9, - 'TPM_SIGNAL_CANCEL_OFF': 10, - 'TPM_SIGNAL_NV_ON': 11, - 'TPM_SIGNAL_NV_OFF': 12, - 'TPM_SIGNAL_KEY_CACHE_ON': 13, - 'TPM_SIGNAL_KEY_CACHE_OFF': 14, - 'TPM_REMOTE_HANDSHAKE': 15, - 'TPM_SET_ALTERNATIVE_RESULT': 16, - 'TPM_SIGNAL_RESET': 17, - 'TPM_SESSION_END': 20, - 'TPM_STOP': 21, - 'TPM_GET_COMMAND_RESPONSE_SIZES': 25, - 'TPM_TEST_FAILURE_MODE': 30, + "TPM_SIGNAL_CANCEL_ON": 9, + "TPM_SIGNAL_CANCEL_OFF": 10, + "TPM_SIGNAL_NV_ON": 11, + "TPM_SIGNAL_NV_OFF": 12, + "TPM_SIGNAL_KEY_CACHE_ON": 13, + "TPM_SIGNAL_KEY_CACHE_OFF": 14, + "TPM_REMOTE_HANDSHAKE": 15, + "TPM_SET_ALTERNATIVE_RESULT": 16, + "TPM_SIGNAL_RESET": 17, + "TPM_SESSION_END": 20, + "TPM_STOP": 21, + "TPM_GET_COMMAND_RESPONSE_SIZES": 25, + "TPM_TEST_FAILURE_MODE": 30, } class TpmSimulator(object): """An object for interacting with the Tpm Simulator.""" - def __init__(self, host: str='localhost', port: int=2321) -> 'TpmSimulator': + + def __init__(self, host: str = "localhost", port: int = 2321) -> "TpmSimulator": """Initialize the simulator on the requested host (ip) and port.""" super(TpmSimulator, self).__init__() @@ -55,27 +57,27 @@ def __init__(self, host: str='localhost', port: int=2321) -> 'TpmSimulator': self.tpmSock.connect((host, port)) # Power cycle the TPM. - self.platSock.send(struct.pack(">L", PLAT_COMMANDS['TPM_SIGNAL_POWER_OFF'])) - self.platSock.send(struct.pack(">L", PLAT_COMMANDS['TPM_SIGNAL_POWER_ON'])) + self.platSock.send(struct.pack(">L", PLAT_COMMANDS["TPM_SIGNAL_POWER_OFF"])) + self.platSock.send(struct.pack(">L", PLAT_COMMANDS["TPM_SIGNAL_POWER_ON"])) # Enable the NV space. - self.platSock.send(struct.pack(">L", PLAT_COMMANDS['TPM_SIGNAL_NV_ON'])) + self.platSock.send(struct.pack(">L", PLAT_COMMANDS["TPM_SIGNAL_NV_ON"])) def send_raw_data(self, data: str) -> None: """Send raw data to the TPM simulator.""" - print("RAW -->: " + str(data).encode('hex')) + print("RAW -->: " + str(data).encode("hex")) self.tpmSock.send(data) def read_raw_data(self, count: int) -> bytes: """Read raw data from the TPM simulator.""" data = self.tpmSock.recv(count) - print("RAW <--: " + str(data).encode('hex')) + print("RAW <--: " + str(data).encode("hex")) return data def send_data(self, data: str) -> bytes: """Send data to the TPM simulator.""" # Send the "I'm about to send data" command. - self.send_raw_data(struct.pack(">L", PLAT_COMMANDS['TPM_SEND_COMMAND'])) + self.send_raw_data(struct.pack(">L", PLAT_COMMANDS["TPM_SEND_COMMAND"])) # Send the locality for the data. self.send_raw_data(struct.pack(">b", 0x03)) # Send the size of the data. @@ -89,7 +91,7 @@ def send_data(self, data: str) -> bytes: while True: result_size = self.read_raw_data(4) result_size = struct.unpack(">L", result_size)[0] - if (result_size > 0): + if result_size > 0: break return self.read_raw_data(result_size) diff --git a/edk2toollib/tpm/tpm2_stream.py b/edk2toollib/tpm/tpm2_stream.py index 3f6487b8..002171ef 100644 --- a/edk2toollib/tpm/tpm2_stream.py +++ b/edk2toollib/tpm/tpm2_stream.py @@ -12,7 +12,8 @@ class Tpm2StreamElement(object): """Tpm2 Stream Element.""" - def __init__(self) -> 'Tpm2StreamElement': + + def __init__(self) -> "Tpm2StreamElement": """Init an empty Tpm2StreamElement.""" self.pack_string = "" @@ -28,7 +29,8 @@ class Tpm2StreamPrimitive(Tpm2StreamElement): size: size of the primitive. 1, 2, 4, or 8 bytes value: Value of primitive """ - def __init__(self, size: int, value: str) -> 'Tpm2StreamPrimitive': + + def __init__(self, size: int, value: str) -> "Tpm2StreamPrimitive": """Init a primitive value. Args: @@ -40,12 +42,7 @@ def __init__(self, size: int, value: str) -> 'Tpm2StreamPrimitive': if size not in (1, 2, 4, 8): raise ValueError("Size must be 1, 2, 4, or 8 bytes!") - self.pack_string = { - 1: ">B", - 2: ">H", - 4: ">L", - 8: ">Q" - }[size] + self.pack_string = {1: ">B", 2: ">H", 4: ">L", 8: ">Q"}[size] self.value = value def marshal(self) -> bytes: @@ -65,7 +62,8 @@ class TPM2_COMMAND_HEADER(Tpm2StreamElement): code: The Code size: The size of the code """ - def __init__(self, tag: str, size: str, code: str) -> 'TPM2_COMMAND_HEADER': + + def __init__(self, tag: str, size: str, code: str) -> "TPM2_COMMAND_HEADER": """Init a Tpm2 command.""" super(TPM2_COMMAND_HEADER, self).__init__() self.tag = tag @@ -88,7 +86,8 @@ def marshal(self) -> str: class TPM2B(Tpm2StreamElement): """Tpm2 B.""" - def __init__(self, data: str) -> 'TPM2B': + + def __init__(self, data: str) -> "TPM2B": """Inits the object.""" super(TPM2B, self).__init__() self.data = data @@ -112,7 +111,8 @@ def marshal(self) -> str: class Tpm2CommandStream(object): """Tpm2 Command Stream.""" - def __init__(self, tag: str, size: int, code: str) -> 'Tpm2CommandStream': + + def __init__(self, tag: str, size: int, code: str) -> "Tpm2CommandStream": """Inits a Tpm2 Command stream object.""" super(Tpm2CommandStream, self).__init__() self.header = TPM2_COMMAND_HEADER(tag, size, code) @@ -124,7 +124,7 @@ def get_size(self) -> int: """Returns the stream size.""" return self.stream_size - def add_element(self, element: 'Tpm2StreamElement') -> None: + def add_element(self, element: "Tpm2StreamElement") -> None: """Adds an element to the stream list.""" self.stream_elements.append(element) self.stream_size += element.get_size() @@ -136,4 +136,4 @@ def get_stream(self) -> str: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - return self.header.marshal() + b''.join(element.marshal() for element in self.stream_elements) + return self.header.marshal() + b"".join(element.marshal() for element in self.stream_elements) diff --git a/edk2toollib/uefi/authenticated_variables_structure_support.py b/edk2toollib/uefi/authenticated_variables_structure_support.py index 43c5cf41..ca6065ee 100644 --- a/edk2toollib/uefi/authenticated_variables_structure_support.py +++ b/edk2toollib/uefi/authenticated_variables_structure_support.py @@ -10,6 +10,7 @@ Each object can be created and or populated from a file stream. Each object can be written to a filesteam as binary and printed to the console in text. """ + import datetime import hashlib import io @@ -37,14 +38,14 @@ # spell-checker: ignore decodefs, createfs, deduplicated, deduplication # UEFI global Variable Namespace -EfiGlobalVarNamespaceUuid = uuid.UUID('8BE4DF61-93CA-11d2-AA0D-00E098032B8C') +EfiGlobalVarNamespaceUuid = uuid.UUID("8BE4DF61-93CA-11d2-AA0D-00E098032B8C") Sha256Oid = [0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01] class CommonUefiStructure(ABC): """This structure contains the methods common across all UEFI Structures.""" - def __init__(self) -> 'CommonUefiStructure': + def __init__(self) -> "CommonUefiStructure": """Inits the object.""" @abstractmethod @@ -73,21 +74,24 @@ def encode(self) -> bytes: """ @abstractmethod - def print(self, outfs: IO=sys.stdout) -> None: + def print(self, outfs: IO = sys.stdout) -> None: """Prints the object to the console.""" class EfiSignatureDataEfiCertX509(CommonUefiStructure): """An object representing a EFI_SIGNATURE_DATA Structure for X509 Certs.""" + STATIC_STRUCT_SIZE = 16 FIXED_SIZE = False - def __init__(self, - decodefs: BinaryIO = None, - decodesize: int=0, - createfs: BinaryIO = None, - cert: bytes = None, - sigowner: uuid.UUID = None) -> 'EfiSignatureDataEfiCertX509': + def __init__( + self, + decodefs: BinaryIO = None, + decodesize: int = 0, + createfs: BinaryIO = None, + cert: bytes = None, + sigowner: uuid.UUID = None, + ) -> "EfiSignatureDataEfiCertX509": """Inits the object. Args: @@ -101,9 +105,9 @@ def __init__(self, (ValueError): Invalid FileStream size (ValueError): Invalid Parameters """ - if (decodefs is not None): + if decodefs is not None: self.decode(decodefs, decodesize) - elif (createfs is not None): + elif createfs is not None: # create a new one self.signature_owner = sigowner # should be 0 but maybe this filestream has other things at the head @@ -112,10 +116,10 @@ def __init__(self, end = createfs.tell() createfs.seek(start) self.signature_data_size = end - start - if (self.signature_data_size < 0): + if self.signature_data_size < 0: raise ValueError("Create File Stream has invalid size") - self.signature_data = (createfs.read(self.signature_data_size)) - elif (cert is not None): + self.signature_data = createfs.read(self.signature_data_size) + elif cert is not None: self.signature_owner = sigowner self.signature_data_size = len(cert) self.signature_data = cert @@ -147,7 +151,7 @@ def SignatureData(self, value: bytes) -> None: warn("SignatureData is deprecated. Use signature_data instead.", DeprecationWarning, 2) self.signature_data = value - def __lt__(self, other: 'EfiSignatureDataEfiCertX509') -> bool: + def __lt__(self, other: "EfiSignatureDataEfiCertX509") -> bool: """Less-than comparison for sorting. Looks at signature_data only, not signature_owner.""" return self.signature_data < other.signature_data @@ -197,38 +201,36 @@ def decode(self, fs: BinaryIO, decodesize: int) -> None: self.signature_owner = uuid.UUID(bytes_le=fs.read(16)) # read remaining decode size for x509 data - self.signature_data_size = decodesize - \ - EfiSignatureDataEfiCertX509.STATIC_STRUCT_SIZE + self.signature_data_size = decodesize - EfiSignatureDataEfiCertX509.STATIC_STRUCT_SIZE self.signature_data = fs.read(self.signature_data_size) - def Print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: + def Print(self, compact: bool = False, outfs: IO = sys.stdout) -> None: """Prints to the console.""" warn("Print() is deprecated. Use print() instead.", DeprecationWarning, 2) self.print(compact=compact, outfs=outfs) - def print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: + def print(self, compact: bool = False, outfs: IO = sys.stdout) -> None: """Prints to the console.""" if not compact: outfs.write("EfiSignatureData - EfiSignatureDataEfiCertX509\n") outfs.write(f" Signature Owner: {str(self.signature_owner)}\n") outfs.write(" Signature Data: \n") - if (self.signature_data is None): + if self.signature_data is None: outfs.write(" NONE\n") else: sdl = self.signature_data if self.signature_data_size != len(sdl): - raise ValueError( - "Invalid Signature Data Size vs Length of data") + raise ValueError("Invalid Signature Data Size vs Length of data") hexdump(sdl, outfs=outfs) else: s = "ESD:EFI_CERT_X509," s += f"{str(self.signature_owner)}," - if (self.signature_data is None): - s += 'NONE' + if self.signature_data is None: + s += "NONE" else: sdl = self.signature_data for index in range(len(sdl)): - s += f'{sdl[index]:02X}' + s += f"{sdl[index]:02X}" outfs.write(s) outfs.write("\n") @@ -283,14 +285,13 @@ def get_total_size(self) -> int: class EfiSignatureDataEfiCertSha256(CommonUefiStructure): """An object representing a EFI_SIGNATURE_DATA Structure for Sha256 Certs.""" + STATIC_STRUCT_SIZE = 16 + hashlib.sha256().digest_size # has guid and array FIXED_SIZE = True - def __init__(self, - decodefs: BinaryIO = None, - createfs: BinaryIO = None, - digest: bytes = None, - sigowner: uuid = None) -> 'EfiSignatureDataEfiCertSha256': + def __init__( + self, decodefs: BinaryIO = None, createfs: BinaryIO = None, digest: bytes = None, sigowner: uuid = None + ) -> "EfiSignatureDataEfiCertSha256": """Inits the object. Args: @@ -305,15 +306,16 @@ def __init__(self, """ if decodefs is not None: self.decode(decodefs) - elif (createfs is not None): + elif createfs is not None: # create a new one self.signature_owner = sigowner - self.signature_data = (hashlib.sha256(createfs.read()).digest()) + self.signature_data = hashlib.sha256(createfs.read()).digest() elif digest is not None: digest_length = len(digest) if digest_length != hashlib.sha256().digest_size: - raise Exception("Invalid digest length (found / expected): (%d / %d)", - digest_length, hashlib.sha256().digest_size) + raise Exception( + "Invalid digest length (found / expected): (%d / %d)", digest_length, hashlib.sha256().digest_size + ) self.signature_owner = sigowner self.signature_data = digest else: @@ -381,13 +383,13 @@ def PopulateFromFileStream(self, fs: BinaryIO) -> None: warn("PopulateFromFileStream() is deprecated. Use decode() instead.", DeprecationWarning, 2) self.decode(fs) - def print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: + def print(self, compact: bool = False, outfs: IO = sys.stdout) -> None: """Prints to the console.""" if not compact: outfs.write("EfiSignatureData - EfiSignatureDataEfiCertSha256\n") outfs.write(f" Signature Owner: {str(self.signature_owner)}\n") outfs.write(" Signature Data: ") - if (self.signature_data is None): + if self.signature_data is None: outfs.write(" NONE\n") else: sdl = self.signature_data @@ -395,10 +397,10 @@ def print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: outfs.write(f"{sdl[index]:02X}") outfs.write("\n") else: - s = 'ESD:EFI_CERT_SHA256,' + s = "ESD:EFI_CERT_SHA256," s += f"{str(self.signature_owner)}," - if (self.signature_data is None): - s += 'NONE' + if self.signature_data is None: + s += "NONE" else: sdl = self.signature_data for index in range(len(sdl)): @@ -406,7 +408,7 @@ def print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: outfs.write(s) outfs.write("\n") - def Print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: + def Print(self, compact: bool = False, outfs: IO = sys.stdout) -> None: """Prints to the console.""" warn("Print() is deprecated. Use print() instead.", DeprecationWarning, 2) self.print(compact, outfs) @@ -470,7 +472,8 @@ def __init__(self, fs, header_size): # noqa class EfiSignatureDataFactory(object): """Factory class for generating an EFI Signature struct.""" - EFI_CERT_SHA256_GUID = uuid.UUID('c1c41626-504c-4092-aca9-41f936934328') + + EFI_CERT_SHA256_GUID = uuid.UUID("c1c41626-504c-4092-aca9-41f936934328") # EFI_CERT_RSA2048_GUID = uuid.UUID("0x3c5766e8, 0x269c, 0x4e34, 0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6") # EFI_CERT_RSA2048_SHA256_GUID = uuid.UUID("0xe2b36190, 0x879b, 0x4a3d, 0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84") # noqa: E501 # EFI_CERT_SHA1_GUID = uuid.UUID("0x826ca512, 0xcf10, 0x4ac9, 0xb1, 0x87, 0xbe, 0x1, 0x49, 0x66, 0x31, 0xbd") @@ -479,18 +482,15 @@ class EfiSignatureDataFactory(object): # EFI_CERT_SHA224_GUID = uuid.UUID("0xb6e5233, 0xa65c, 0x44c9, 0x94, 0x7, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd") # EFI_CERT_SHA384_GUID = uuid.UUID("0xff3e5307, 0x9fd0, 0x48c9, 0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1") # EFI_CERT_SHA512_GUID = uuid.UUID("0x93e0fae, 0xa6c4, 0x4f50, 0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a") - EFI_CERT_X509_SHA256_GUID = uuid.UUID( - "3bd2a492-96c0-4079-b420-fcf98ef103ed") + EFI_CERT_X509_SHA256_GUID = uuid.UUID("3bd2a492-96c0-4079-b420-fcf98ef103ed") # EFI_CERT_X509_SHA384_GUID = uuid.UUID("0x7076876e, 0x80c2, 0x4ee6, 0xaa, 0xd2, 0x28, 0xb3, 0x49, 0xa6, 0x86, 0x5b") # noqa: E501 # EFI_CERT_X509_SHA512_GUID = uuid.UUID("0x446dbf63, 0x2502, 0x4cda, 0xbc, 0xfa, 0x24, 0x65, 0xd2, 0xb0, 0xfe, 0x9d") # noqa: E501 # EFI_CERT_TYPE_PKCS7_GUID = uuid.UUID("0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7") @staticmethod def factory( - fs: BinaryIO, - type: uuid.UUID, - size: int - )-> Union[EfiSignatureDataEfiCertSha256, EfiSignatureDataEfiCertX509]: + fs: BinaryIO, type: uuid.UUID, size: int + ) -> Union[EfiSignatureDataEfiCertSha256, EfiSignatureDataEfiCertX509]: """This method is a factory for creating the correct Efi Signature Data object from the filestream. Uses a Filestream of an existing auth payload. @@ -500,15 +500,15 @@ def factory( type: Guid of the type size: decodesize for x509, struct size for Sha256 """ - if (fs is None): + if fs is None: raise Exception("Invalid File stream") - if (type == EfiSignatureDataFactory.EFI_CERT_SHA256_GUID): - if (size != EfiSignatureDataEfiCertSha256.STATIC_STRUCT_SIZE): + if type == EfiSignatureDataFactory.EFI_CERT_SHA256_GUID: + if size != EfiSignatureDataEfiCertSha256.STATIC_STRUCT_SIZE: raise Exception("Invalid Size 0x%x" % size) return EfiSignatureDataEfiCertSha256(decodefs=fs) - elif (type == EfiSignatureDataFactory.EFI_CERT_X509_GUID): + elif type == EfiSignatureDataFactory.EFI_CERT_X509_GUID: return EfiSignatureDataEfiCertX509(decodefs=fs, decodesize=size) else: @@ -517,9 +517,7 @@ def factory( @staticmethod def Factory( - fs: BinaryIO, - type: uuid.UUID, - size: int + fs: BinaryIO, type: uuid.UUID, size: int ) -> Union[EfiSignatureDataEfiCertSha256, EfiSignatureDataEfiCertX509]: """This method is a factory for creating the correct Efi Signature Data object from the filestream. @@ -535,9 +533,7 @@ def Factory( @staticmethod def Create( - type: uuid.UUID, - ContentFileStream: BinaryIO, - sigowner: uuid.UUID + type: uuid.UUID, ContentFileStream: BinaryIO, sigowner: uuid.UUID ) -> Union[EfiSignatureDataEfiCertSha256, EfiSignatureDataEfiCertX509]: """Create a new EFI Sginature Data Object. @@ -551,9 +547,7 @@ def Create( @staticmethod def create( - type: uuid.UUID, - ContentFileStream: BinaryIO, - sigowner: uuid.UUID + type: uuid.UUID, ContentFileStream: BinaryIO, sigowner: uuid.UUID ) -> Union[EfiSignatureDataEfiCertSha256, EfiSignatureDataEfiCertX509]: """Create a new EFI Sginature Data Object. @@ -562,12 +556,12 @@ def create( ContentFileStream: filestream to read sigowner: the uuid object of the signature owner guid """ - if (ContentFileStream is None): + if ContentFileStream is None: raise Exception("Invalid Content File Stream") - if (type == EfiSignatureDataFactory.EFI_CERT_SHA256_GUID): + if type == EfiSignatureDataFactory.EFI_CERT_SHA256_GUID: return EfiSignatureDataEfiCertSha256(createfs=ContentFileStream, sigowner=sigowner) - elif (type == EfiSignatureDataFactory.EFI_CERT_X509_GUID): + elif type == EfiSignatureDataFactory.EFI_CERT_X509_GUID: return EfiSignatureDataEfiCertX509(createfs=ContentFileStream, sigowner=sigowner) else: raise Exception("Not Supported") @@ -575,17 +569,17 @@ def create( class EfiSignatureList(CommonUefiStructure): """An object representing a EFI_SIGNATURE_LIST.""" + STATIC_STRUCT_SIZE = 16 + 4 + 4 + 4 - def __init__(self, filestream: BinaryIO = None, typeguid: uuid.UUID = None) -> 'EfiSignatureList': + def __init__(self, filestream: BinaryIO = None, typeguid: uuid.UUID = None) -> "EfiSignatureList": """Inits the object. Args: filestream (:obj:`BinaryIO`, optional): a filestream object of binary content that is the structure encoded typeguid (:obj:`uuid.UUID`, optional): type guid """ - if (filestream is None): - + if filestream is None: # Type of the signature. GUID signature types are defined in below. self.signature_type = typeguid @@ -649,35 +643,31 @@ def decode(self, fs: BinaryIO) -> None: self.signature_size = struct.unpack(" 0): - self.signature_header = EfiSignatureHeader( - fs, self.signature_header_size) + if self.signature_header_size > 0: + self.signature_header = EfiSignatureHeader(fs, self.signature_header_size) - if (((self.signature_list_size - (fs.tell() - start)) % self.signature_size) != 0): - raise Exception( - "Invalid Sig List. Signature Data Array is not a valid size") + if ((self.signature_list_size - (fs.tell() - start)) % self.signature_size) != 0: + raise Exception("Invalid Sig List. Signature Data Array is not a valid size") self.signature_data_list = [] while (start + self.signature_list_size) > fs.tell(): # double check that everything is adding up correctly. if (start + self.signature_list_size - fs.tell() - self.signature_size) < 0: - raise Exception( - "Invalid Signature List Processing. Signature Data not correctly parsed!!") - a = EfiSignatureDataFactory.factory( - fs, self.signature_type, self.signature_size) + raise Exception("Invalid Signature List Processing. Signature Data not correctly parsed!!") + a = EfiSignatureDataFactory.factory(fs, self.signature_type, self.signature_size) self.signature_data_list.append(a) def PopulateFromFileStream(self, fs: BinaryIO) -> None: @@ -695,12 +685,12 @@ def PopulateFromFileStream(self, fs: BinaryIO) -> None: warn("PopulateFromFileStream() is deprecated, use decode() instead.", DeprecationWarning, 2) self.decode(fs) - def Print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: + def Print(self, compact: bool = False, outfs: IO = sys.stdout) -> None: """Prints to the console.""" warn("Print() is deprecated, use print() instead().", DeprecationWarning, 2) self.print(compact=compact, outfs=outfs) - def print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: + def print(self, compact: bool = False, outfs: IO = sys.stdout) -> None: """Prints to the console.""" if not compact: outfs.write("EfiSignatureList\n") @@ -708,7 +698,7 @@ def print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: outfs.write(f" Signature List Size: {self.signature_list_size:0x}\n") outfs.write(f" Signature Header Size: {self.signature_header_size:0x}\n") outfs.write(f" Signature Size: {self.signature_size:0x}\n") - if (self.signature_header is not None): + if self.signature_header is not None: self.signature_header.print(compact=compact, outfs=outfs) else: outfs.write(" Signature Header: NONE\n") @@ -718,14 +708,14 @@ def print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: csv += f",{self.signature_list_size:0x}" csv += f",{self.signature_header_size:0x}" csv += f",{self.signature_size:0x}" - if (self.signature_header is not None): + if self.signature_header is not None: csv += self.signature_header.print(compact=compact, outfs=outfs) else: csv += ",NONE" outfs.write(csv) - outfs.write('\n') + outfs.write("\n") - if (self.signature_data_list is not None): + if self.signature_data_list is not None: for a in self.signature_data_list: a.print(compact=compact, outfs=outfs) @@ -746,19 +736,19 @@ def write(self, fs: BinaryIO) -> None: (Exception): Invalid filestream (Exception): Uninitialized Sig header """ - if (fs is None): + if fs is None: raise Exception("Invalid File Output Stream") - if ((self.signature_header is None) and (self.signature_header_size == -1)): + if (self.signature_header is None) and (self.signature_header_size == -1): raise Exception("Invalid object. Uninitialized Sig Header") fs.write(self.signature_type.bytes_le) fs.write(struct.pack(" bytes: self.write(fs) return fs.getvalue() - def AddSignatureHeader(self, SigHeader: bytes, SigSize: int=0) -> None: + def AddSignatureHeader(self, SigHeader: bytes, SigSize: int = 0) -> None: """Adds the Signature Header. Raises: (Exception): Signature header already set """ - if (self.signature_header is not None): + if self.signature_header is not None: raise Exception("Signature Header already set") - if (self.signature_header_size != -1): + if self.signature_header_size != -1: raise Exception("Signature Header already set (size)") - if (self.signature_size != 0): + if self.signature_size != 0: raise Exception("Signature Size already set") - if (self.signature_data_list is not None): + if self.signature_data_list is not None: raise Exception("Signature Data List is already initialized") self.signature_header = SigHeader - if (SigHeader is None): + if SigHeader is None: self.signature_header_size = 0 self.signature_size = SigSize else: @@ -801,62 +791,56 @@ def AddSignatureHeader(self, SigHeader: bytes, SigSize: int=0) -> None: self.signature_list_size += self.signature_header_size def AddSignatureData( - self, - SigDataObject: Tuple['EfiSignatureDataEfiCertX509', 'EfiSignatureDataEfiCertSha256'] + self, SigDataObject: Tuple["EfiSignatureDataEfiCertX509", "EfiSignatureDataEfiCertSha256"] ) -> None: """Adds the Signature Data. Raises: (Exception): Signature size does not match Sig Data Object size """ - if (self.signature_size == 0): - raise Exception( - "Before adding Signature Data you must have set the Signature Size") + if self.signature_size == 0: + raise Exception("Before adding Signature Data you must have set the Signature Size") - if (self.signature_size != SigDataObject.get_total_size()): + if self.signature_size != SigDataObject.get_total_size(): raise Exception("Can't add Signature Data of different size") - if (self.signature_data_list is None): + if self.signature_data_list is None: self.signature_data_list = [] self.signature_data_list.append(SigDataObject) self.signature_list_size += self.signature_size - def MergeSignatureList(self, esl: 'EfiSignatureList') -> None: + def MergeSignatureList(self, esl: "EfiSignatureList") -> None: """Add the EfiSignatureData entries within the supplied EfiSignatureList to the current object. No sorting or deduplication is performed, the EfiSignatureData elements are simply appended """ if not isinstance(esl, EfiSignatureList): - raise Exception( - "Parameter 1 'esl' must be of type EfiSignatureList") + raise Exception("Parameter 1 'esl' must be of type EfiSignatureList") - if (self.signature_type != esl.signature_type): + if self.signature_type != esl.signature_type: raise Exception("Signature Types must match") - if (self.signature_header_size > 0 - or esl.signature_header_size > 0): + if self.signature_header_size > 0 or esl.signature_header_size > 0: raise Exception("Merge does not support Signature Headers") self.signature_header_size = 0 - if (esl.signature_list_size == EfiSignatureList.STATIC_STRUCT_SIZE): + if esl.signature_list_size == EfiSignatureList.STATIC_STRUCT_SIZE: # supplied EfiSignatureList is empty, return return FixedSizeData = esl.signature_data_list[0].FIXED_SIZE if not FixedSizeData: - raise Exception( - "Can only merge EfiSignatureLists with fixed-size data elements") + raise Exception("Can only merge EfiSignatureLists with fixed-size data elements") - if (self.signature_data_list is None): + if self.signature_data_list is None: self.signature_data_list = [] self.signature_size = esl.signature_size self.signature_data_list += esl.signature_data_list - self.signature_list_size += esl.signature_list_size - \ - EfiSignatureList.STATIC_STRUCT_SIZE + self.signature_list_size += esl.signature_list_size - EfiSignatureList.STATIC_STRUCT_SIZE - def SortBySignatureDataValue(self, deduplicate: bool = True) -> 'EfiSignatureList': + def SortBySignatureDataValue(self, deduplicate: bool = True) -> "EfiSignatureList": """Sort self's signature_data_list by signature_data values (ignores SigOwner) & optionally deduplicate. When deduplicate is true, remove duplicate signature_data values from self and return them in an @@ -873,21 +857,19 @@ def SortBySignatureDataValue(self, deduplicate: bool = True) -> 'EfiSignatureLis dupes.signature_data_list = [] # if nothing to sort, return the empty dupe list - if (self.signature_data_list is None - or len(self.signature_data_list) == 1): + if self.signature_data_list is None or len(self.signature_data_list) == 1: return dupes - self.signature_data_list.sort(key=attrgetter('signature_data')) + self.signature_data_list.sort(key=attrgetter("signature_data")) - if (deduplicate is False): + if deduplicate is False: return dupes # return empty dupe list without performing deduplicate # perform deduplicate on self last = len(self.signature_data_list) - 1 # index of the last item for i in range(last - 1, -1, -1): if self.signature_data_list[last].signature_data == self.signature_data_list[i].signature_data: - dupes.signature_data_list.insert( - 0, self.signature_data_list[last]) + dupes.signature_data_list.insert(0, self.signature_data_list[last]) dupes.signature_list_size += self.signature_size del self.signature_data_list[last] self.signature_list_size -= self.signature_size @@ -896,7 +878,7 @@ def SortBySignatureDataValue(self, deduplicate: bool = True) -> 'EfiSignatureLis last = i # only initialize dupes.signature_size if duplicate elements are present - if (len(dupes.signature_data_list) > 0): + if len(dupes.signature_data_list) > 0: dupes.signature_size = self.signature_size return dupes @@ -908,7 +890,7 @@ class EfiSignatureDatabase(CommonUefiStructure): Useful for parsing and building the contents of the Secure Boot variables """ - def __init__(self, filestream: BinaryIO = None, esl_list: List[EfiSignatureList] = None) -> 'EfiSignatureDatabase': + def __init__(self, filestream: BinaryIO = None, esl_list: List[EfiSignatureList] = None) -> "EfiSignatureDatabase": """Inits an Efi Signature Database object. Args: @@ -944,14 +926,14 @@ def decode(self, fs: BinaryIO, decodesize: int = -1) -> None: (Exception): Invalid filestream (Exception): Invalid filestream size """ - if (fs is None): + if fs is None: raise Exception("Invalid File Stream") self.esl_list = [] begin = fs.tell() fs.seek(0, io.SEEK_END) end = fs.tell() # end is offset after last byte fs.seek(begin) - while (fs.tell() != end): + while fs.tell() != end: Esl = EfiSignatureList(fs) self.esl_list.append(Esl) @@ -967,12 +949,12 @@ def PopulateFromFileStream(self, fs: BinaryIO) -> None: """ return self.decode(fs) - def print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: + def print(self, compact: bool = False, outfs: IO = sys.stdout) -> None: """Prints to the console.""" for Esl in self.esl_list: Esl.print(compact=compact, outfs=outfs) - def Print(self, compact: bool = False, outfs: IO=sys.stdout) -> None: + def Print(self, compact: bool = False, outfs: IO = sys.stdout) -> None: """Prints to the console.""" warn("Print() is deprecated, use print() instead.", DeprecationWarning, 2) self.print(compact=compact, outfs=outfs) @@ -992,7 +974,7 @@ def write(self, fs: BinaryIO) -> None: Raises: (Exception): Invalid filestream """ - if (fs is None): + if fs is None: raise Exception("Invalid File Output Stream") for Esl in self.esl_list: Esl.write(fs) @@ -1008,7 +990,7 @@ def encode(self) -> bytes: self.write(fs) return fs.getvalue() - def get_canonical_and_dupes(self) -> tuple['EfiSignatureDatabase', 'EfiSignatureDatabase']: + def get_canonical_and_dupes(self) -> tuple["EfiSignatureDatabase", "EfiSignatureDatabase"]: """Compute and return a tuple containing both a canonicalized database & a database of duplicates. Returns: @@ -1027,21 +1009,20 @@ def get_canonical_and_dupes(self) -> tuple['EfiSignatureDatabase', 'EfiSignature x509eslList = None for Esl in self.esl_list: - if (Esl.signature_data_list is None): # discard empty EfiSignatureLists + if Esl.signature_data_list is None: # discard empty EfiSignatureLists continue - if (Esl.signature_type == EfiSignatureDataFactory.EFI_CERT_SHA256_GUID): - if (sha256esl is None): + if Esl.signature_type == EfiSignatureDataFactory.EFI_CERT_SHA256_GUID: + if sha256esl is None: sha256esl = Esl # initialize it else: sha256esl.MergeSignatureList(Esl) - elif (Esl.signature_type == EfiSignatureDataFactory.EFI_CERT_X509_GUID): - if (x509eslList is None): + elif Esl.signature_type == EfiSignatureDataFactory.EFI_CERT_X509_GUID: + if x509eslList is None: x509eslList = [Esl] # initialize it else: x509eslList.append(Esl) else: - raise Exception("Unsupported signature type %s", - Esl.signature_type) + raise Exception("Unsupported signature type %s", Esl.signature_type) # for each type, sort and de-duplicate, and then populate the respective databases # note the ordering of this section is the prescribed canonical order @@ -1051,13 +1032,13 @@ def get_canonical_and_dupes(self) -> tuple['EfiSignatureDatabase', 'EfiSignature canonicalDb = EfiSignatureDatabase() duplicatesDb = EfiSignatureDatabase() - if (sha256esl is not None): + if sha256esl is not None: dupes = sha256esl.SortBySignatureDataValue(deduplicate=True) canonicalDb.esl_list.append(sha256esl) duplicatesDb.esl_list.append(dupes) - if (x509eslList is not None): - x509eslList.sort(key=attrgetter('signature_data_list')) + if x509eslList is not None: + x509eslList.sort(key=attrgetter("signature_data_list")) for esl in x509eslList: if not canonicalDb.esl_list: canonicalDb.esl_list.append(esl) @@ -1068,7 +1049,7 @@ def get_canonical_and_dupes(self) -> tuple['EfiSignatureDatabase', 'EfiSignature return (canonicalDb, duplicatesDb) - def GetCanonicalAndDupes(self) -> tuple['EfiSignatureDatabase', 'EfiSignatureDatabase']: + def GetCanonicalAndDupes(self) -> tuple["EfiSignatureDatabase", "EfiSignatureDatabase"]: """Compute and return a tuple containing both a canonicalized database & a database of duplicates. Returns: @@ -1084,22 +1065,22 @@ def GetCanonicalAndDupes(self) -> tuple['EfiSignatureDatabase', 'EfiSignatureDat warn("GetCanonicalAndDupes() is deprecated. Use get_canonical_and_dupes() instead.", DeprecationWarning, 2) return self.get_canonical_and_dupes() - def get_canonical(self) -> 'EfiSignatureDatabase': + def get_canonical(self) -> "EfiSignatureDatabase": """Return a canonicalized EfiSignatureDatabase, see GetCanonicalAndDupes() for more details.""" canonical, _ = self.get_canonical_and_dupes() return canonical - def GetCanonical(self) -> 'EfiSignatureDatabase': + def GetCanonical(self) -> "EfiSignatureDatabase": """Return a canonicalized EfiSignatureDatabase, see GetCanonicalAndDupes() for more details.""" warn("GetCanonical() is deprecated. Use get_canonical() instead.", DeprecationWarning, 2) return self.get_canonical() - def get_duplicates(self) -> 'EfiSignatureDatabase': + def get_duplicates(self) -> "EfiSignatureDatabase": """Return an EfiSignatureDatabase of duplicates, see GetCanonicalAndDupes() for more details.""" _, dupes = self.get_canonical_and_dupes() return dupes - def GetDuplicates(self) -> 'EfiSignatureDatabase': + def GetDuplicates(self) -> "EfiSignatureDatabase": """Return an EfiSignatureDatabase of duplicates, see GetCanonicalAndDupes() for more details.""" warn("GetDuplicates() is deprecated. Use get_duplicates() instead.", DeprecationWarning, 2) return self.get_duplicates() @@ -1107,10 +1088,11 @@ def GetDuplicates(self) -> 'EfiSignatureDatabase': class EfiTime(CommonUefiStructure): """Object representing an EFI_TIME.""" - _StructFormat = ' 'EfiTime': + def __init__(self, time: datetime.datetime = datetime.datetime.now(), decodefs: BinaryIO = None) -> "EfiTime": """Inits an EFI_TIME object. Args: @@ -1154,11 +1136,10 @@ def decode(self, fs: BinaryIO) -> datetime.datetime: nano_second, time_zone, day_light, - _ # Pad2 + _, # Pad2 ) = struct.unpack(EfiTime._StructFormat, fs.read(EfiTime._StructSize)) - self.time = datetime.datetime( - year, month, day, hour, minute, second, nano_second // 1000) + self.time = datetime.datetime(year, month, day, hour, minute, second, nano_second // 1000) logging.debug("Timezone value is: 0x%x" % time_zone) logging.debug("Daylight value is: 0x%X" % day_light) @@ -1177,15 +1158,14 @@ def PopulateFromFileStream(self, fs: BinaryIO) -> datetime.datetime: warn("PopulateFromFileStream() is deprecated, use decode() instead", DeprecationWarning, 2) return self.decode(fs) - def Print(self, outfs: IO=sys.stdout) -> None: + def Print(self, outfs: IO = sys.stdout) -> None: """Prints to the console.""" warn("Print() is deprecated, use print() instead", DeprecationWarning, 2) return self.print(outfs) - def print(self, outfs: IO=sys.stdout) -> None: + def print(self, outfs: IO = sys.stdout) -> None: """Prints to the console.""" - outfs.write("\nEfiTime: %s\n" % datetime.datetime.strftime( - self.time, "%A, %B %d, %Y %I:%M%p")) + outfs.write("\nEfiTime: %s\n" % datetime.datetime.strftime(self.time, "%A, %B %d, %Y %I:%M%p")) def Encode(self) -> bytes: """Return's time as a packed EfiTime Structure.""" @@ -1206,7 +1186,7 @@ def encode(self) -> bytes: 0, # Nano Seconds 0, # Daylight 0, # TimeZone - 0 # Pad2 + 0, # Pad2 ) def write(self, fs: IO) -> None: @@ -1238,10 +1218,8 @@ class EfiVariableAuthentication2(CommonUefiStructure): """An object representing a EFI_VARIABLE_AUTHENTICATION_2.""" def __init__( - self, - time: datetime.datetime=datetime.datetime.now(), - decodefs: BinaryIO=None - ) -> 'EfiVariableAuthentication2': + self, time: datetime.datetime = datetime.datetime.now(), decodefs: BinaryIO = None + ) -> "EfiVariableAuthentication2": """Inits an EFI_VARIABLE_AUTHENTICATION_2 object. Args: @@ -1273,7 +1251,7 @@ def encode(self) -> bytes: return buffer - def Encode(self, outfs: BinaryIO=None) -> bytes: + def Encode(self, outfs: BinaryIO = None) -> bytes: """Encodes a new variable into a binary representation. Args: @@ -1299,7 +1277,7 @@ def decode(self, fs: BinaryIO) -> None: Raises: (Exception): Invalid filestream """ - if (fs is None): + if fs is None: raise Exception("Invalid File Steam") self.time = EfiTime(decodefs=fs) self.auth_info = WinCert.factory(fs) @@ -1320,7 +1298,7 @@ def PopulateFromFileStream(self, fs: BinaryIO) -> None: warn("PopulateFromFileStream() is deprecated, use decode() instead.", DeprecationWarning, 2) self.decode(fs) - def print(self, outfs: IO=sys.stdout) -> None: + def print(self, outfs: IO = sys.stdout) -> None: """Prints to the console.""" outfs.write("EfiVariableAuthentication2\n") self.time.print(outfs) @@ -1333,11 +1311,11 @@ def print(self, outfs: IO=sys.stdout) -> None: elif self.payload is not None: outfs.write("Raw Data: \n") sdl = self.payload.tolist() - if (self.payload_size != len(sdl)): + if self.payload_size != len(sdl): raise Exception("Invalid Payload Data Size vs Length of data") hexdump(sdl, outfs=outfs) - def Print(self, outfs: IO=sys.stdout) -> None: + def Print(self, outfs: IO = sys.stdout) -> None: """Prints to the console.""" warn("Print() is deprecated, use print() instead.", DeprecationWarning, 2) self.print(outfs=outfs) @@ -1401,8 +1379,7 @@ def set_payload(self, fs: BinaryIO) -> None: fs.seek(start) self.payload_size = end - start if self.payload_size == 0: - logging.debug( - "No Payload for this EfiVariableAuthenticated2 Object") + logging.debug("No Payload for this EfiVariableAuthenticated2 Object") return # Variables with the GUID EFI_IMAGE_SECURITY_DATABASE_GUID are formatted @@ -1426,9 +1403,9 @@ def __init__( name: str, guid: str, attributes: Union[int, str], - payload: Optional[Union[io.BytesIO, bytes]]=None, - efi_time: datetime.datetime=datetime.datetime.now() - ) -> 'EfiVariableAuthentication2Builder': + payload: Optional[Union[io.BytesIO, bytes]] = None, + efi_time: datetime.datetime = datetime.datetime.now(), + ) -> "EfiVariableAuthentication2Builder": """Builds a EfiVariableAuthentication2 structure. Args: @@ -1459,8 +1436,12 @@ def __init__( raise ValueError(f"guid is not the correct type: {type(guid)}") # This is the digest being signed that all signer's must sign - self.digest_without_payload = name.encode('utf_16_le') + \ - guid.bytes_le + efi_attributes.encode() + self.authenticated_variable.time.encode() + self.digest_without_payload = ( + name.encode("utf_16_le") + + guid.bytes_le + + efi_attributes.encode() + + self.authenticated_variable.time.encode() + ) # Allow a caller to swap out the payload self.digest = self.digest_without_payload @@ -1490,7 +1471,7 @@ def update_payload(self, payload: Union[io.BytesIO, bytes]) -> None: return # convert the payload to a file stream for SetPayload - if not hasattr(payload, 'seek'): + if not hasattr(payload, "seek"): payload = io.BytesIO(payload) # Get the starting position and the length @@ -1504,10 +1485,11 @@ def update_payload(self, payload: Union[io.BytesIO, bytes]) -> None: self.authenticated_variable.set_payload(payload) def sign( - self, signing_certificate: Certificate, + self, + signing_certificate: Certificate, signing_private_key: RSAPrivateKey, additional_certificates: List = [], - **kwargs: Any + **kwargs: Any, ) -> None: """Signs an authenticated variable. @@ -1538,7 +1520,8 @@ def sign( logging.info("%sSubject: %s", indent, signing_certificate.subject) self.signature_builder = self.signature_builder.add_signer( - signing_certificate, signing_private_key, hash_algorithm) + signing_certificate, signing_private_key, hash_algorithm + ) for i, cert in enumerate(additional_certificates): indents = indent * i @@ -1550,7 +1533,7 @@ def sign( # Add the certificate for verification self.signature_builder = self.signature_builder.add_certificate(cert.certificate) - def finalize(self, omit_content_info: bool=True) -> EfiVariableAuthentication2: + def finalize(self, omit_content_info: bool = True) -> EfiVariableAuthentication2: """Finalizes the signature and returns a EfiVariableAuthentication2. Args: @@ -1565,8 +1548,7 @@ def finalize(self, omit_content_info: bool=True) -> EfiVariableAuthentication2: # - The signature is detached # - Do not convert LF to CRLF in the file (windows format) # - Remove the attributes section from the pkcs7 structure - options = [pkcs7.PKCS7Options.DetachedSignature, - pkcs7.PKCS7Options.Binary, pkcs7.PKCS7Options.NoAttributes] + options = [pkcs7.PKCS7Options.DetachedSignature, pkcs7.PKCS7Options.Binary, pkcs7.PKCS7Options.NoAttributes] # The signature is enclosed in a asn1 content info structure self.signature = self.signature_builder.sign(Encoding.DER, options) @@ -1574,16 +1556,14 @@ def finalize(self, omit_content_info: bool=True) -> EfiVariableAuthentication2: # Up until recently including the content info section (on tianocore edk2 based implementations) # will cause UEFI to return `SECURITY_VIOLATION`` if omit_content_info: - content_info, _ = der_decode( - self.signature, asn1Spec=rfc2315.ContentInfo()) + content_info, _ = der_decode(self.signature, asn1Spec=rfc2315.ContentInfo()) - content_type = content_info.getComponentByName('contentType') + content_type = content_info.getComponentByName("contentType") if content_type != rfc2315.signedData: raise ValueError("This wasn't a signed data structure?") # Remove the contentInfo section and just return the sign data - signed_data, _ = der_decode(content_info.getComponentByName( - 'content'), asn1Spec=rfc2315.SignedData()) + signed_data, _ = der_decode(content_info.getComponentByName("content"), asn1Spec=rfc2315.SignedData()) self.signature = der_encode(signed_data) @@ -1594,18 +1574,20 @@ def finalize(self, omit_content_info: bool=True) -> EfiVariableAuthentication2: class EFiVariableAuthentication2(EfiVariableAuthentication2): """An object representing a EFI_VARIABLE_AUTHENTICATION_2. DEPRECATED.""" + def __init__( - self, - time: datetime.datetime=datetime.datetime.now(), - decodefs: - BinaryIO=None - ) -> 'EFiVariableAuthentication2': + self, time: datetime.datetime = datetime.datetime.now(), decodefs: BinaryIO = None + ) -> "EFiVariableAuthentication2": """DEPRECATED. Use EfiVariableAuthentication2() instead. Initializes a EFiVariableAuthentication2.""" - warn("EFiVariableAuthentication2() is deprecated, use EfiVariableAuthentication2() instead.", DeprecationWarning, 2) # noqa: E501 + warn( + "EFiVariableAuthentication2() is deprecated, use EfiVariableAuthentication2() instead.", + DeprecationWarning, + 2, + ) # noqa: E501 super().__init__(time, decodefs=decodefs) -''' +""" THESE ARE NOT SUPPORTED IN THE TOOL ``` @@ -1646,4 +1628,4 @@ def __init__( EFI_TIME TimeOfRevocation; } EFI_CERT_X509_SHA512; ``` -''' +""" diff --git a/edk2toollib/uefi/bmp_object.py b/edk2toollib/uefi/bmp_object.py index a3d052f1..70bdae1d 100644 --- a/edk2toollib/uefi/bmp_object.py +++ b/edk2toollib/uefi/bmp_object.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Module for reading and parsing bitmap graphics files.""" + import logging import struct from typing import IO, Optional @@ -28,9 +29,10 @@ class BmpColorMap(object): } BMP_COLOR_MAP; ``` """ + STATIC_SIZE = 4 - def __init__(self, filestream: Optional[IO]=None) -> 'BmpColorMap': + def __init__(self, filestream: Optional[IO] = None) -> "BmpColorMap": """Inits an empty object or loads from an fs.""" if filestream is None: self.Blue = 0 @@ -108,15 +110,16 @@ class BmpObject(object): } BMP_IMAGE_HEADER; ``` """ + STATIC_FILE_HEADER_SIZE = 14 STATIC_IMAGE_HEADER_SIZE = 40 - def __init__(self, filestream: Optional[IO]=None) -> 'BmpObject': + def __init__(self, filestream: Optional[IO] = None) -> "BmpObject": """Inits an empty object or loads from filestream.""" self.logger = logging.getLogger(__name__) if filestream is None: - self.CharB = 'B' - self.CharM = 'M' + self.CharB = "B" + self.CharM = "M" self.Size = BmpObject.STATIC_STRUCT_SIZE self.Rsvd16_1 = 0 self.Rsvd16_2 = 0 @@ -146,11 +149,11 @@ def __init__(self, filestream: Optional[IO]=None) -> 'BmpObject': def ExpectedColorMapEntires(self) -> int: """Returns expected entries depending on BitPerPixel.""" - if (self.BitPerPixel == 1): + if self.BitPerPixel == 1: return 2 - elif (self.BitPerPixel == 4): + elif self.BitPerPixel == 4: return 16 - elif (self.BitPerPixel == 8): + elif self.BitPerPixel == 8: return 256 else: return 0 @@ -176,12 +179,10 @@ def PopulateFromFileStream(self, fs: IO) -> None: end = fs.tell() fs.seek(offset) - self.logger.debug("Bmp File size as determined by file is: 0x%X (%d)" % ( - end - offset, end - offset)) + self.logger.debug("Bmp File size as determined by file is: 0x%X (%d)" % (end - offset, end - offset)) - if ((end - offset) < BmpObject.STATIC_FILE_HEADER_SIZE): # size of the static file header data - raise Exception( - "Invalid file stream size. %d < File Header Size" % (end - offset)) + if (end - offset) < BmpObject.STATIC_FILE_HEADER_SIZE: # size of the static file header data + raise Exception("Invalid file stream size. %d < File Header Size" % (end - offset)) # read the BMP File header self.CharB = struct.unpack("=c", fs.read(1))[0] @@ -191,9 +192,8 @@ def PopulateFromFileStream(self, fs: IO) -> None: self.Rsvd16_2 = struct.unpack("=H", fs.read(2))[0] self.ImageOffset = struct.unpack("=I", fs.read(4))[0] - if ((end - fs.tell()) < BmpObject.STATIC_IMAGE_HEADER_SIZE): - raise Exception( - "Invalid file stream size. %d < Img Header Size" % (end - fs.tell())) + if (end - fs.tell()) < BmpObject.STATIC_IMAGE_HEADER_SIZE: + raise Exception("Invalid file stream size. %d < Img Header Size" % (end - fs.tell())) # read the BMP Image Header self.HeaderSize = struct.unpack("=I", fs.read(4))[0] @@ -208,18 +208,19 @@ def PopulateFromFileStream(self, fs: IO) -> None: self.NumberOfColors = struct.unpack("=I", fs.read(4))[0] self.ImportantColors = struct.unpack("=I", fs.read(4))[0] - if (self.Size < self.HeaderSize): + if self.Size < self.HeaderSize: raise Exception("Size can't be smaller than HeaderSize") - if ((end - fs.tell()) < (self.Size - self.HeaderSize - BmpObject.STATIC_FILE_HEADER_SIZE)): - raise Exception("Invalid file stream size (Size) 0x%X Less Than 0x%X" % ( - (end - fs.tell()), (self.Size - self.HeaderSize - BmpObject.STATIC_FILE_HEADER_SIZE))) + if (end - fs.tell()) < (self.Size - self.HeaderSize - BmpObject.STATIC_FILE_HEADER_SIZE): + raise Exception( + "Invalid file stream size (Size) 0x%X Less Than 0x%X" + % ((end - fs.tell()), (self.Size - self.HeaderSize - BmpObject.STATIC_FILE_HEADER_SIZE)) + ) StartOfImageData = offset + self.ImageOffset - if (fs.tell() < StartOfImageData): - + if fs.tell() < StartOfImageData: # Handle any color maps - if (self.ExpectedColorMapEntires() > 0): + if self.ExpectedColorMapEntires() > 0: ColorMapCount = self.ExpectedColorMapEntires() if (self.NumberOfColors > 0) and (self.NumberOfColors != ColorMapCount): self.logger.info("Current Code has untested support for limited color map, Good Luck. ") @@ -227,7 +228,7 @@ def PopulateFromFileStream(self, fs: IO) -> None: self.logger.info("Actual Color Map Entries %d" % (self.NumberOfColors)) ColorMapCount = self.NumberOfColors - if ((StartOfImageData - fs.tell()) < (ColorMapCount * BmpColorMap.STATIC_SIZE)): + if (StartOfImageData - fs.tell()) < (ColorMapCount * BmpColorMap.STATIC_SIZE): raise Exception("Color Map not as expected") # read all the color maps and append to the list @@ -240,11 +241,10 @@ def PopulateFromFileStream(self, fs: IO) -> None: self.ImageData = fs.read(self.Size - self.ImageOffset) - if ((end - fs.tell()) > 0): - raise Exception( - "Extra Data at the end of BMP file - 0x%X bytes" % (end - fs.tell())) + if (end - fs.tell()) > 0: + raise Exception("Extra Data at the end of BMP file - 0x%X bytes" % (end - fs.tell())) - def Print(self, PrintImageData: bool=False, PrintColorMapData: bool=False) -> None: + def Print(self, PrintImageData: bool = False, PrintColorMapData: bool = False) -> None: """Prints to logger. Args: @@ -272,18 +272,18 @@ def Print(self, PrintImageData: bool=False, PrintColorMapData: bool=False) -> No self.logger.info(" NumberOfColors: %d" % self.NumberOfColors) self.logger.info(" ImportantColors: %d" % self.ImportantColors) # print color maps - if (PrintColorMapData): + if PrintColorMapData: for cm in self.ColorMapList: cm.Print() - if (self._PaddingLength > 0): + if self._PaddingLength > 0: self.logger.info(" BMP Padding (0x%X bytes)" % self._PaddingLength) ndbl = memoryview(self._Padding).tolist() for index in range(len(ndbl)): - if (index % 16 == 0): - self.logger.info("0x%04X -" % index), - self.logger.info(" %02X" % ndbl[index]), - if (index % 16 == 15): + if index % 16 == 0: + (self.logger.info("0x%04X -" % index),) + (self.logger.info(" %02X" % ndbl[index]),) + if index % 16 == 15: self.logger.info("") self.logger.info("") @@ -291,10 +291,10 @@ def Print(self, PrintImageData: bool=False, PrintColorMapData: bool=False) -> No self.logger.info(" Bmp Image Data: ") ndbl = memoryview(self.ImageData).tolist() for index in range(len(ndbl)): - if (index % 16 == 0): - self.logger.info("0x%04X -" % index), - self.logger.info(" %02X" % ndbl[index]), - if (index % 16 == 15): + if index % 16 == 0: + (self.logger.info("0x%04X -" % index),) + (self.logger.info(" %02X" % ndbl[index]),) + if index % 16 == 15: self.logger.info("") self.logger.info("") @@ -330,9 +330,9 @@ def Write(self, fs: IO) -> bytes: cm.Write(fs) # padding - if (self._PaddingLength > 0): + if self._PaddingLength > 0: fs.write(self.Padding) # Pixel data - if (self.ImageData): + if self.ImageData: fs.write(self.ImageData) diff --git a/edk2toollib/uefi/edk2/build_objects/dsc.py b/edk2toollib/uefi/edk2/build_objects/dsc.py index 667e25fe..f9114e50 100644 --- a/edk2toollib/uefi/edk2/build_objects/dsc.py +++ b/edk2toollib/uefi/edk2/build_objects/dsc.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Data model for the EDK II DSC.""" + # There will be some overlap between the objects for DSC files and FDF files import collections from typing import Any, Optional @@ -15,7 +16,8 @@ class dsc_set(set): """a DSC set object.""" - def __init__(self, allowed_classes: list=None) -> 'dsc_set': + + def __init__(self, allowed_classes: list = None) -> "dsc_set": """Initializes an empty set.""" if allowed_classes is None: allowed_classes = [] @@ -40,9 +42,9 @@ class dsc_dict(collections.OrderedDict): def __init__( self, - allowed_key_classes: Optional[str]=None, - allowed_value_classes: Optional[Any]=None # noqa: ANN401 - ) -> 'dsc_dict': + allowed_key_classes: Optional[str] = None, + allowed_value_classes: Optional[Any] = None, # noqa: ANN401 + ) -> "dsc_dict": """Initializes a dsc_dict.""" if allowed_key_classes is None: allowed_key_classes = [] @@ -81,7 +83,8 @@ def __setitem__(self, key: int, val: str) -> None: if isinstance(val, dsc_set): if val._allowed_classes != self._allowed_value_classes: raise ValueError( - f"Cannot add set:{val._allowed_classes} to restricted dict: {self._allowed_value_classes}") + f"Cannot add set:{val._allowed_classes} to restricted dict: {self._allowed_value_classes}" + ) elif type(val) not in self._allowed_value_classes: raise ValueError(f"Cannot add {type(val)} to restricted dict: {self._allowed_value_classes}") if key in self: @@ -92,29 +95,54 @@ def __setitem__(self, key: int, val: str) -> None: class dsc: """Class representing a DSC.""" - def __init__(self, file_path: Optional[str]=None) -> 'dsc': + + def __init__(self, file_path: Optional[str] = None) -> "dsc": """Inits dsc type.""" # The EDK2 path to this particular DSC, if is is None it means it was created from a stream and has no file self.file_path = file_path # parameters added for clarity self.skus = dsc_set(allowed_classes=[definition, sku_id]) # this is a set of SKUs - self.components = dsc_dict(allowed_key_classes=[dsc_section_type, ], - allowed_value_classes=[component, definition]) - self.libraries = dsc_dict(allowed_key_classes=[dsc_section_type, ], - allowed_value_classes=[library, definition]) - self.library_classes = dsc_dict(allowed_key_classes=[dsc_section_type, ], - allowed_value_classes=[library_class, definition]) - self.build_options = dsc_dict(allowed_key_classes=[dsc_buildoption_section_type, ], - allowed_value_classes=[build_option, definition]) - self.pcds = dsc_dict(allowed_key_classes=[dsc_pcd_section_type, ], - allowed_value_classes=[pcd, pcd_typed, pcd_variable]) - self.defines = dsc_set(allowed_classes=[definition, ]) + self.components = dsc_dict( + allowed_key_classes=[ + dsc_section_type, + ], + allowed_value_classes=[component, definition], + ) + self.libraries = dsc_dict( + allowed_key_classes=[ + dsc_section_type, + ], + allowed_value_classes=[library, definition], + ) + self.library_classes = dsc_dict( + allowed_key_classes=[ + dsc_section_type, + ], + allowed_value_classes=[library_class, definition], + ) + self.build_options = dsc_dict( + allowed_key_classes=[ + dsc_buildoption_section_type, + ], + allowed_value_classes=[build_option, definition], + ) + self.pcds = dsc_dict( + allowed_key_classes=[ + dsc_pcd_section_type, + ], + allowed_value_classes=[pcd, pcd_typed, pcd_variable], + ) + self.defines = dsc_set( + allowed_classes=[ + definition, + ] + ) self.default_stores = dsc_set(allowed_classes=[definition, default_store]) # NEXTVER: should we populate the default information into the DSC object? # FOR EXAMPLE: default_stores and skus - def __eq__(self, other: 'dsc') -> bool: + def __eq__(self, other: "dsc") -> bool: """Enables equality comparisons (a == b). Warning: @@ -145,12 +173,25 @@ class dsc_section_type: arch (str): architecture module_type (str): module type """ - dsc_module_types = ["COMMON", "BASE", "SEC", "PEI_CORE", "PEIM", "DXE_CORE", - "DXE_DRIVER", "DXE_RUNTIME_DRIVER", "DXE_SAL_DRIVER", - "DXE_SMM_DRIVER", "SMM_CORE", "UEFI_DRIVER", - "UEFI_APPLICATION", "USER_DEFINED"] - def __init__(self, arch: str="common", module_type: str="common") -> 'dsc_section_type': + dsc_module_types = [ + "COMMON", + "BASE", + "SEC", + "PEI_CORE", + "PEIM", + "DXE_CORE", + "DXE_DRIVER", + "DXE_RUNTIME_DRIVER", + "DXE_SAL_DRIVER", + "DXE_SMM_DRIVER", + "SMM_CORE", + "UEFI_DRIVER", + "UEFI_APPLICATION", + "USER_DEFINED", + ] + + def __init__(self, arch: str = "common", module_type: str = "common") -> "dsc_section_type": """Inits dsc section type.""" self.arch = arch.upper().strip() self.module_type = module_type.upper().strip() @@ -162,7 +203,7 @@ def __hash__(self) -> int: arch = "*" if (self.arch == "COMMON" or self.arch == "DEFAULT") else self.arch return hash((arch, self.module_type)) - def __eq__(self, other: 'dsc_section_type') -> bool: + def __eq__(self, other: "dsc_section_type") -> bool: """Enables equality comparisons (a == b).""" if type(other) is not dsc_section_type: return False @@ -176,7 +217,7 @@ def __repr__(self) -> str: return attributes @classmethod - def IsValidModuleType(cls: 'dsc_section_type', name: str) -> bool: + def IsValidModuleType(cls: "dsc_section_type", name: str) -> bool: """If the module type is valid or not.""" return name in cls.dsc_module_types @@ -197,11 +238,10 @@ class dsc_buildoption_section_type(dsc_section_type): BuildOptions ``` """ + def __init__( - self, arch: str="common", - codebase: str="common", - module_type: str="common" - ) -> 'dsc_buildoption_section_type': + self, arch: str = "common", codebase: str = "common", module_type: str = "common" + ) -> "dsc_buildoption_section_type": """Inits dsc build option section type.""" super().__init__(arch, module_type) self.codebase = codebase.upper().strip() @@ -209,7 +249,7 @@ def __init__( raise ValueError(f"{codebase} is not a valid codebase type") @classmethod - def IsValidCodeBase(cls: 'dsc_buildoption_section_type', codebase: str) -> bool: + def IsValidCodeBase(cls: "dsc_buildoption_section_type", codebase: str) -> bool: """Determines if codebase is valid. Args: @@ -224,7 +264,7 @@ def __hash__(self) -> int: """Returns the hash of an object for hashtables.""" return hash((super().__hash__(), self.codebase)) - def __eq__(self, other: 'dsc_buildoption_section_type') -> bool: + def __eq__(self, other: "dsc_buildoption_section_type") -> bool: """Enables equality comparisons (a == b).""" if type(other) is not dsc_buildoption_section_type: return False @@ -237,11 +277,21 @@ def __repr__(self) -> str: return f"{self.arch}.{self.codebase}.{self.module_type}" -dsc_pcd_types = ["FEATUREFLAG", "PATCHABLEINMODULE", "FIXEDATBUILD", "DYNAMIC", "DYNAMICEX", - "DYNAMICDEFAULT", "DYNAMICHII", "DYNAMICVPD", "DYNAMICEXHII", "DYNAMICEXVPD"] +dsc_pcd_types = [ + "FEATUREFLAG", + "PATCHABLEINMODULE", + "FIXEDATBUILD", + "DYNAMIC", + "DYNAMICEX", + "DYNAMICDEFAULT", + "DYNAMICHII", + "DYNAMICVPD", + "DYNAMICEXHII", + "DYNAMICEXVPD", +] -class dsc_pcd_section_type(): +class dsc_pcd_section_type: """This class is uses to define the PCD section type inside a component. Attributes: @@ -250,13 +300,10 @@ class dsc_pcd_section_type(): sku: defaults to DEFAULT store: if none, we don't have anything done """ + def __init__( - self, - pcdtype: str, - arch: str="common", - sku: str="DEFAULT", - store: Optional[str]=None - ) -> 'dsc_pcd_section_type': + self, pcdtype: str, arch: str = "common", sku: str = "DEFAULT", store: Optional[str] = None + ) -> "dsc_pcd_section_type": """Inits the dsc_pcd_section object.""" # if store is none, then we don't have anything done self.arch = arch.upper().strip() @@ -277,7 +324,7 @@ def __repr__(self) -> str: store = "" if self.default_store is None else f".{self.default_store}" return f"Pcds{self.pcd_type}.{self.arch}.{self.sku}{store}" - def __eq__(self, other: 'dsc_pcd_section_type') -> bool: + def __eq__(self, other: "dsc_pcd_section_type") -> bool: """Enables equality comparisons (a == b).""" if type(other) is not dsc_pcd_section_type: return False @@ -287,7 +334,7 @@ def __eq__(self, other: 'dsc_pcd_section_type') -> bool: class dsc_pcd_component_type(dsc_pcd_section_type): """This class is uses to define the PCD type inside a component.""" - def __init__(self, pcdtype: str) -> 'dsc_pcd_component_type': + def __init__(self, pcdtype: str) -> "dsc_pcd_component_type": """Inits the dsc_pcd_component object.""" super().__init__(pcdtype) @@ -299,7 +346,7 @@ def __hash__(self) -> int: """Returns the hash of an object for hashtables.""" return hash(self.pcd_type) - def __eq__(self, other: 'dsc_pcd_component_type') -> bool: + def __eq__(self, other: "dsc_pcd_component_type") -> bool: """Enables equality comparisons (a == b).""" if type(other) is not dsc_pcd_component_type: return False @@ -317,19 +364,15 @@ class sku_id: """ def __init__( - self, - id: int=0, - name: str="DEFAULT", - parent: str="DEFAULT", - source_info: Optional['source_info']=None - ) -> 'sku_id': + self, id: int = 0, name: str = "DEFAULT", parent: str = "DEFAULT", source_info: Optional["source_info"] = None + ) -> "sku_id": """Inits the sku_id object.""" self.id = id self.name = name self.parent = parent # the default parent is default self.source_info = source_info - def __eq__(self, other: 'sku_id') -> bool: + def __eq__(self, other: "sku_id") -> bool: """Enables equality comparisons (a == b).""" if type(other) is not sku_id: return False @@ -351,7 +394,7 @@ def __repr__(self) -> str: class component: """Contains the data for a component for the EDK build system to build.""" - def __init__(self, inf: str, source_info: Optional['source_info']=None) -> 'component': + def __init__(self, inf: str, source_info: Optional["source_info"] = None) -> "component": """Inits the component object.""" self.library_classes = set() # a list of libraries that this component uses self.pcds = {} # a dictionary of PCD's that are keyed by dsc_pcd_component_type, they are sets @@ -360,9 +403,9 @@ def __init__(self, inf: str, source_info: Optional['source_info']=None) -> 'comp self.inf = inf # the EDK2 relative path to the source INF self.source_info = source_info - def __eq__(self, other: 'component') -> bool: + def __eq__(self, other: "component") -> bool: """Enables equality comparisons (a == b).""" - if (type(other) is not component): + if type(other) is not component: return False return self.inf == other.inf # NEXTVER: should this be case insensitive? @@ -387,12 +430,8 @@ class definition: """ def __init__( - self, - name: str, - value: str, - local: bool=False, - source_info: Optional['source_info']=None - ) -> 'definition': + self, name: str, value: str, local: bool = False, source_info: Optional["source_info"] = None + ) -> "definition": """Inits the definition object. NOTE: Local means DEFINE is in front and is localized to that particular section @@ -414,9 +453,9 @@ def __hash__(self) -> int: """Returns the hash of an object for hashtables.""" return hash(self.name) - def __eq__(self, other: 'definition') -> bool: + def __eq__(self, other: "definition") -> bool: """Enables equality comparisons (a == b).""" - if (type(other) is not definition): + if type(other) is not definition: return False return other.name == self.name @@ -429,12 +468,12 @@ class library: source_info (:obj:`obj`, optional): source info """ - def __init__(self, inf: str, source_info: Optional['source_info']=None) -> 'library': + def __init__(self, inf: str, source_info: Optional["source_info"] = None) -> "library": """Inits the Library object.""" self.inf = inf self.source_info = source_info - def __eq__(self, other: 'library') -> bool: + def __eq__(self, other: "library") -> bool: """Enables equality comparisons (a == b).""" if type(other) is not library: return False @@ -458,7 +497,7 @@ class library_class: source_info: source info """ - def __init__(self, libraryclass: str, inf: str, source_info: Optional['source_info']=None) -> 'library_class': + def __init__(self, libraryclass: str, inf: str, source_info: Optional["source_info"] = None) -> "library_class": """Inits the Library class object. Args: @@ -470,9 +509,9 @@ def __init__(self, libraryclass: str, inf: str, source_info: Optional['source_in self.inf = inf self.source_info = source_info - def __eq__(self, other: 'library_class') -> bool: + def __eq__(self, other: "library_class") -> bool: """Enables equality comparisons (a == b).""" - if (type(other) is not library_class): + if type(other) is not library_class: return False # if they're both null if self.libraryclass.lower() == "null" and other.libraryclass.lower() == "null": @@ -482,7 +521,7 @@ def __eq__(self, other: 'library_class') -> bool: def __hash__(self) -> int: """Returns the hash of an object for hashtables.""" # if we're a null lib, we want the hash to be based on the inf path - if (self.libraryclass.lower() == "null"): + if self.libraryclass.lower() == "null": return hash(self.inf) else: return hash(self.libraryclass) @@ -504,7 +543,7 @@ class pcd: EXAMPLE: PcdTokenSpaceGuidCName.PcdCName|Value """ - def __init__(self, namespace: str, name: str, value: str, source_info: Optional['source_info']=None) -> 'pcd': + def __init__(self, namespace: str, name: str, value: str, source_info: Optional["source_info"] = None) -> "pcd": """Inits a PCD object. Args: @@ -518,7 +557,7 @@ def __init__(self, namespace: str, name: str, value: str, source_info: Optional[ self.value = value self.source_info = source_info - def __eq__(self, other: 'pcd') -> bool: + def __eq__(self, other: "pcd") -> bool: """Enables equality comparisons (a == b).""" if not issubclass(other.__class__, pcd): return False @@ -549,9 +588,9 @@ def __init__( name: str, value: str, datum_type: str, - max_size: int=0, - source_info: Optional['source_info']=None - ) -> 'pcd_typed': + max_size: int = 0, + source_info: Optional["source_info"] = None, + ) -> "pcd_typed": """Inits the Typed PCD Object.""" super().__init__(namespace, name, value, source_info) self.datum_type = datum_type @@ -586,10 +625,10 @@ def __init__( var_name: str, var_guid: str, var_offset: str, - default: Optional[str]=None, - attributes: Optional[str]=None, - source_info: Optional['source_info']=None - ) -> 'pcd_variable': + default: Optional[str] = None, + attributes: Optional[str] = None, + source_info: Optional["source_info"] = None, + ) -> "pcd_variable": """Inits a pcd_variable object.""" super().__init__(namespace, name, "", source_info) if attributes is None: @@ -629,19 +668,20 @@ class build_option: NOTE: Contains the data for a build option EX: MSFT:*_*_*_CC_FLAGS = /D MDEPKG_NDEBUG """ + # {FAMILY}:{TARGET}_{TAGNAME}_{ARCH}_{TOOLCODE}_{ATTRIBUTE} def __init__( self, tool_code: str, attribute: str, data: str, - target: str="*", - tagname: str="*", - arch: str="*", - family: Optional[str]=None, - replace: bool=False, - source_info: 'source_info'=None - ) -> 'build_option': + target: str = "*", + tagname: str = "*", + arch: str = "*", + family: Optional[str] = None, + replace: bool = False, + source_info: "source_info" = None, + ) -> "build_option": """Inits a build_option object. Args: @@ -673,9 +713,9 @@ def __init__( self.data = data self.source_info = source_info - def __eq__(self, other: 'build_option') -> bool: + def __eq__(self, other: "build_option") -> bool: """Enables equality comparisons (a == b).""" - if (type(other) is not build_option): + if type(other) is not build_option: return False if self.family != other.family: return False @@ -695,7 +735,7 @@ def __hash__(self) -> int: """Returns the hash of an object for hashtables.""" return hash(self.__repr__(False)) - def __repr__(self, include_data: bool=True) -> str: + def __repr__(self, include_data: bool = True) -> str: """A string representation of the object.""" rep = "" if self.family is None else f"{self.family}:" rep += "_".join((self.target, self.tagname, self.arch, self.tool_code, self.attribute)) @@ -712,10 +752,11 @@ class default_store: value: defaults to "Standard" source_info: defaults to None """ - ''' contains the information on a default store. ''' - ''' 0 | Standard # UEFI Standard default ''' - def __init__(self, index: int=0, value: str="Standard", source_info: Optional[str]=None) -> 'default_store': + """ contains the information on a default store. """ + """ 0 | Standard # UEFI Standard default """ + + def __init__(self, index: int = 0, value: str = "Standard", source_info: Optional[str] = None) -> "default_store": """Inits a default store object. NOTE: Local means DEFINE is in front and is localized to that particular section @@ -732,9 +773,9 @@ def __hash__(self) -> int: """Returns the hash of an object for hashtables.""" return hash(self.index) - def __eq__(self, other: 'default_store') -> bool: + def __eq__(self, other: "default_store") -> bool: """Enables equality comparisons (a == b).""" - if (type(other) is not default_store): + if type(other) is not default_store: return False return other.index == self.index @@ -746,7 +787,8 @@ class source_info: file (str): filename lineno (:obj:`int`, optional): line number """ - def __init__(self, file: str, lineno: int = None) -> 'source_info': + + def __init__(self, file: str, lineno: int = None) -> "source_info": """Inits a source_info object.""" self.file = file self.lineno = lineno diff --git a/edk2toollib/uefi/edk2/build_objects/dsc_translator.py b/edk2toollib/uefi/edk2/build_objects/dsc_translator.py index d402b963..72b7ad3a 100644 --- a/edk2toollib/uefi/edk2/build_objects/dsc_translator.py +++ b/edk2toollib/uefi/edk2/build_objects/dsc_translator.py @@ -4,6 +4,7 @@ # # SPDX-License-Identifier: BSD-2-Clause-Patent """Translates a DSC object into a file.""" + import logging import os @@ -21,10 +22,11 @@ ) -class DscTranslator(): +class DscTranslator: """A class used to translate DSCs.""" + @classmethod - def dsc_to_file(cls: 'DscTranslator', dsc_obj: dsc, filepath: str) -> None: + def dsc_to_file(cls: "DscTranslator", dsc_obj: dsc, filepath: str) -> None: """Transforms the DSC object to a file.""" file_path = os.path.abspath(filepath) f = open(file_path, "w") @@ -34,10 +36,10 @@ def dsc_to_file(cls: 'DscTranslator', dsc_obj: dsc, filepath: str) -> None: f.close() @classmethod - def _GetDscLinesFromDscObj(cls: 'DscTranslator', obj: dsc, depth: int=0) -> list: + def _GetDscLinesFromDscObj(cls: "DscTranslator", obj: dsc, depth: int = 0) -> list: """Gets the DSC strings for an data model objects.""" lines = [] - depth_pad = ''.ljust(depth) + depth_pad = "".ljust(depth) org_depth = depth depth += 2 @@ -101,12 +103,10 @@ def _GetDscLinesFromDscObj(cls: 'DscTranslator', obj: dsc, depth: int=0) -> list if obj.default is None: lines.append(f"{pcd_name}|{obj.var_guid}|{obj.var_offset}") elif len(obj.attributes) == 0: - lines.append( - f"{pcd_name}|{obj.var_guid}|{obj.var_offset}|{obj.default}") + lines.append(f"{pcd_name}|{obj.var_guid}|{obj.var_offset}|{obj.default}") else: attr = ", ".join(obj.attributes) - lines.append( - f"{pcd_name}|{obj.var_guid}|{obj.var_offset}|{obj.default}|{attr}") + lines.append(f"{pcd_name}|{obj.var_guid}|{obj.var_offset}|{obj.default}|{attr}") elif type(obj) is build_option: rep = depth_pad if obj.family is None else f"{depth_pad}{obj.family}:" @@ -118,12 +118,15 @@ def _GetDscLinesFromDscObj(cls: 'DscTranslator', obj: dsc, depth: int=0) -> list return lines @classmethod - def _FormatComponent(cls: 'DscTranslator', comp: dsc, depth: int=0) -> list[str]: - has_subsection = len(comp.pcds) > 0 or len(comp.defines) > 0 or len( - comp.build_options) > 0 or len(comp.library_classes) > 0 - depth_pad = ''.ljust(depth) + def _FormatComponent(cls: "DscTranslator", comp: dsc, depth: int = 0) -> list[str]: + has_subsection = ( + len(comp.pcds) > 0 or len(comp.defines) > 0 or len(comp.build_options) > 0 or len(comp.library_classes) > 0 + ) + depth_pad = "".ljust(depth) if not has_subsection: - return [f"{depth_pad}{comp.inf}", ] + return [ + f"{depth_pad}{comp.inf}", + ] lines = [] org_depth_pad = depth_pad depth_pad += " " # add two more onto our pad diff --git a/edk2toollib/uefi/edk2/fmp_payload_header.py b/edk2toollib/uefi/edk2/fmp_payload_header.py index b2ea2837..c384857b 100644 --- a/edk2toollib/uefi/edk2/fmp_payload_header.py +++ b/edk2toollib/uefi/edk2/fmp_payload_header.py @@ -17,14 +17,14 @@ def _SIGNATURE_32(A: str, B: str, C: str, D: str) -> bytes: - return struct.unpack('=I', bytearray(A + B + C + D, 'ascii'))[0] + return struct.unpack("=I", bytearray(A + B + C + D, "ascii"))[0] def _SIGNATURE_32_TO_STRING(Signature: int) -> bytes: return struct.pack(" 'FmpPayloadHeaderClass': + def __init__(self) -> "FmpPayloadHeaderClass": """Inits an empty object.""" self.Signature = self._FMP_PAYLOAD_HEADER_SIGNATURE self.HeaderSize = self._StructSize self.FwVersion = 0x00000000 self.LowestSupportedVersion = 0x00000000 - self.Payload = b'' + self.Payload = b"" def Encode(self) -> bytes: r"""Serializes the Header + payload. @@ -56,11 +57,7 @@ def Encode(self) -> bytes: (bytes): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ FmpPayloadHeader = struct.pack( - self._StructFormat, - self.Signature, - self.HeaderSize, - self.FwVersion, - self.LowestSupportedVersion + self._StructFormat, self.Signature, self.HeaderSize, self.FwVersion, self.LowestSupportedVersion ) return FmpPayloadHeader + self.Payload @@ -81,8 +78,7 @@ def Decode(self, Buffer: bytes) -> bytes: if len(Buffer) < self._StructSize: raise ValueError (Signature, HeaderSize, FwVersion, LowestSupportedVersion) = struct.unpack( - self._StructFormat, - Buffer[0:self._StructSize] + self._StructFormat, Buffer[0 : self._StructSize] ) if Signature != self._FMP_PAYLOAD_HEADER_SIGNATURE: raise ValueError @@ -92,16 +88,22 @@ def Decode(self, Buffer: bytes) -> bytes: self.HeaderSize = HeaderSize self.FwVersion = FwVersion self.LowestSupportedVersion = LowestSupportedVersion - self.Payload = Buffer[self.HeaderSize:] + self.Payload = Buffer[self.HeaderSize :] return self.Payload def DumpInfo(self) -> None: """Prints payload header information.""" - print('FMP_PAYLOAD_HEADER.Signature = {Signature:08X} ({SignatureString})' - .format(Signature=self.Signature, SignatureString=_SIGNATURE_32_TO_STRING(self.Signature))) - print('FMP_PAYLOAD_HEADER.HeaderSize = {HeaderSize:08X}'.format(HeaderSize=self.HeaderSize)) - print('FMP_PAYLOAD_HEADER.FwVersion = {FwVersion:08X}'.format(FwVersion=self.FwVersion)) - print('FMP_PAYLOAD_HEADER.LowestSupportedVersion = {LowestSupportedVersion:08X}' - .format(LowestSupportedVersion=self.LowestSupportedVersion)) - print('sizeof (Payload) = {Size:08X}'.format(Size=len(self.Payload))) + print( + "FMP_PAYLOAD_HEADER.Signature = {Signature:08X} ({SignatureString})".format( + Signature=self.Signature, SignatureString=_SIGNATURE_32_TO_STRING(self.Signature) + ) + ) + print("FMP_PAYLOAD_HEADER.HeaderSize = {HeaderSize:08X}".format(HeaderSize=self.HeaderSize)) + print("FMP_PAYLOAD_HEADER.FwVersion = {FwVersion:08X}".format(FwVersion=self.FwVersion)) + print( + "FMP_PAYLOAD_HEADER.LowestSupportedVersion = {LowestSupportedVersion:08X}".format( + LowestSupportedVersion=self.LowestSupportedVersion + ) + ) + print("sizeof (Payload) = {Size:08X}".format(Size=len(self.Payload))) diff --git a/edk2toollib/uefi/edk2/ftw_working_block_format.py b/edk2toollib/uefi/edk2/ftw_working_block_format.py index e32a95a0..0c5655db 100644 --- a/edk2toollib/uefi/edk2/ftw_working_block_format.py +++ b/edk2toollib/uefi/edk2/ftw_working_block_format.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Module contains helper classes for working with FaultTolerant Working block content.""" + import struct import sys import uuid @@ -33,7 +34,8 @@ class EfiFtwWorkingBlockHeader(object): UINT64 WriteQueueSize; } EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER; """ - def __init__(self) -> 'EfiFtwWorkingBlockHeader': + + def __init__(self) -> "EfiFtwWorkingBlockHeader": """Initializes an empty object.""" self.StructString = "=16sLBBBBQ" # spell-checker: disable-line self.Signature = None @@ -44,7 +46,7 @@ def __init__(self) -> 'EfiFtwWorkingBlockHeader': self.Reserved3 = None self.WriteQueueSize = None - def load_from_file(self, file: IO) -> 'EfiFtwWorkingBlockHeader': + def load_from_file(self, file: IO) -> "EfiFtwWorkingBlockHeader": """Loads an EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER from a file. Args: @@ -63,11 +65,18 @@ def load_from_file(self, file: IO) -> 'EfiFtwWorkingBlockHeader': file.seek(orig_seek) # Load this object with the contents of the data. - (signature_bin, self.Crc, self.WorkingBlockValidFields, self.Reserved1, self.Reserved2, self.Reserved3, - self.WriteQueueSize) = struct.unpack(self.StructString, struct_bytes) + ( + signature_bin, + self.Crc, + self.WorkingBlockValidFields, + self.Reserved1, + self.Reserved2, + self.Reserved3, + self.WriteQueueSize, + ) = struct.unpack(self.StructString, struct_bytes) # Update the GUID to be a UUID object. - if sys.byteorder == 'big': + if sys.byteorder == "big": self.Signature = uuid.UUID(bytes=signature_bin) else: self.Signature = uuid.UUID(bytes_le=signature_bin) @@ -84,9 +93,17 @@ def serialize(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - signature_bin = self.Signature.bytes if sys.byteorder == 'big' else self.Signature.bytes_le - return struct.pack(self.StructString, signature_bin, self.Crc, self.WorkingBlockValidFields, - self.Reserved1, self.Reserved2, self.Reserved3, self.WriteQueueSize) + signature_bin = self.Signature.bytes if sys.byteorder == "big" else self.Signature.bytes_le + return struct.pack( + self.StructString, + signature_bin, + self.Crc, + self.WorkingBlockValidFields, + self.Reserved1, + self.Reserved2, + self.Reserved3, + self.WriteQueueSize, + ) class EfiFtwWriteHeader(object): @@ -104,7 +121,8 @@ class EfiFtwWriteHeader(object): UINT64 PrivateDataSize; } EFI_FAULT_TOLERANT_WRITE_HEADER; """ - def __init__(self) -> 'EfiFtwWriteHeader': + + def __init__(self) -> "EfiFtwWriteHeader": """Initializes an empty object.""" self.StructString = "=BBBB16sLQQ" self.StatusBits = None @@ -116,7 +134,7 @@ def __init__(self) -> 'EfiFtwWriteHeader': self.NumberOfWrites = None self.PrivateDataSize = None - def load_from_file(self, file: IO) -> 'EfiFtwWriteHeader': + def load_from_file(self, file: IO) -> "EfiFtwWriteHeader": """Loads an EFI_FAULT_TOLERANT_WRITE_HEADER from a file. Args: @@ -132,9 +150,16 @@ def load_from_file(self, file: IO) -> 'EfiFtwWriteHeader': file.seek(orig_seek) # Load this object with the contents of the data. - (self.StatusBits, self.ReservedByte1, self.ReservedByte2, self.ReservedByte3, self.CallerId, - self.ReservedUint32, self.NumberOfWrites, self.PrivateDataSize) = struct.unpack(self.StructString, - struct_bytes) + ( + self.StatusBits, + self.ReservedByte1, + self.ReservedByte2, + self.ReservedByte3, + self.CallerId, + self.ReservedUint32, + self.NumberOfWrites, + self.PrivateDataSize, + ) = struct.unpack(self.StructString, struct_bytes) return self @@ -144,9 +169,17 @@ def serialize(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - return struct.pack(self.StructString, self.StatusBits, self.ReservedByte1, self.ReservedByte2, - self.ReservedByte3, self.CallerId, self.ReservedUint32, self.NumberOfWrites, - self.PrivateDataSize) + return struct.pack( + self.StructString, + self.StatusBits, + self.ReservedByte1, + self.ReservedByte2, + self.ReservedByte3, + self.CallerId, + self.ReservedUint32, + self.NumberOfWrites, + self.PrivateDataSize, + ) class EfiFtwWriteRecord(object): @@ -165,7 +198,8 @@ class EfiFtwWriteRecord(object): INT64 RelativeOffset; } EFI_FAULT_TOLERANT_WRITE_RECORD; """ - def __init__(self) -> 'EfiFtwWriteRecord': + + def __init__(self) -> "EfiFtwWriteRecord": """Initializes an empty object.""" self.StructString = "=BBBBLQQQQ" # spell-checker: disable-line self.StatusBits = None @@ -178,7 +212,7 @@ def __init__(self) -> 'EfiFtwWriteRecord': self.Length = None self.RelativeOffset = None - def load_from_file(self, file: IO) -> 'EfiFtwWriteRecord': + def load_from_file(self, file: IO) -> "EfiFtwWriteRecord": """Loads an EFI_FAULT_TOLERANT_WRITE_RECORD from a file. Args: @@ -194,8 +228,17 @@ def load_from_file(self, file: IO) -> 'EfiFtwWriteRecord': file.seek(orig_seek) # Load this object with the contents of the data. - (self.StatusBits, self.ReservedByte1, self.ReservedByte2, self.ReservedByte3, self.ReservedUint32, self.Lba, - self.Offset, self.Length, self.RelativeOffset) = struct.unpack(self.StructString, struct_bytes) + ( + self.StatusBits, + self.ReservedByte1, + self.ReservedByte2, + self.ReservedByte3, + self.ReservedUint32, + self.Lba, + self.Offset, + self.Length, + self.RelativeOffset, + ) = struct.unpack(self.StructString, struct_bytes) return self @@ -205,6 +248,15 @@ def serialize(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - return struct.pack(self.StructString, self.StatusBits, self.ReservedByte1, self.ReservedByte2, - self.ReservedByte3, self.ReservedUint32, self.Lba, self.Offset, self.Length, - self.RelativeOffset) + return struct.pack( + self.StructString, + self.StatusBits, + self.ReservedByte1, + self.ReservedByte2, + self.ReservedByte3, + self.ReservedUint32, + self.Lba, + self.Offset, + self.Length, + self.RelativeOffset, + ) diff --git a/edk2toollib/uefi/edk2/guid_list.py b/edk2toollib/uefi/edk2/guid_list.py index edf8f357..67265ff6 100644 --- a/edk2toollib/uefi/edk2/guid_list.py +++ b/edk2toollib/uefi/edk2/guid_list.py @@ -7,6 +7,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Simple list of GuidListEntry objects parsed from edk2 specific files.""" + import logging import os from typing import IO @@ -16,7 +17,7 @@ from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser -class GuidListEntry(): +class GuidListEntry: """A object representing a Guid. Attributes: @@ -24,7 +25,8 @@ class GuidListEntry(): guid (str): registry format guid in string format filepath (str): absolute path to file where this guid was found """ - def __init__(self, name: str, guid: str, filepath: str) -> 'GuidListEntry': + + def __init__(self, name: str, guid: str, filepath: str) -> "GuidListEntry": """Create GuidListEntry for later review and compare. Args: @@ -41,8 +43,9 @@ def __str__(self) -> str: return f"GUID: {self.guid} NAME: {self.name} FILE: {self.absfilepath}" -class GuidList(): +class GuidList: """Static class for returning Guids.""" + @staticmethod def guidlist_from_filesystem(folder: str, ignore_lines: list = list()) -> list: """Create a list of GuidListEntry from files found in the file system. @@ -59,13 +62,13 @@ def guidlist_from_filesystem(folder: str, ignore_lines: list = list()) -> list: for root, dirs, files in os.walk(folder): for d in dirs[:]: fullpath = os.path.join(root, d) - if (ignore(fullpath)): + if ignore(fullpath): logging.debug(f"Ignore folder: {fullpath}") dirs.remove(d) for name in files: fullpath = os.path.join(root, name) - if (ignore(fullpath)): + if ignore(fullpath): logging.debug(f"Ignore file: {fullpath}") continue @@ -83,10 +86,10 @@ def parse_guids_from_edk2_file(filename: str) -> list: Returns: (list[GuidListEntry]): guids """ - if (filename.lower().endswith(".dec")): + if filename.lower().endswith(".dec"): with open(filename, "r") as f: return GuidList.parse_guids_from_dec(f, filename) - elif (filename.lower().endswith(".inf")): + elif filename.lower().endswith(".inf"): return GuidList.parse_guids_from_inf(filename) else: return [] diff --git a/edk2toollib/uefi/edk2/parsers/base_parser.py b/edk2toollib/uefi/edk2/parsers/base_parser.py index 88efbd2d..45199c65 100644 --- a/edk2toollib/uefi/edk2/parsers/base_parser.py +++ b/edk2toollib/uefi/edk2/parsers/base_parser.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Code to support parsing EDK2 files.""" + import logging import os from typing import Optional, Union @@ -27,9 +28,10 @@ class BaseParser(object): PPs (list): List of PPs TargetFilePath (list): file being parsed """ + operators = ["OR", "AND", "IN", "==", "!=", ">", "<", "<=", ">="] - def __init__(self, log: str="BaseParser") -> 'BaseParser': + def __init__(self, log: str = "BaseParser") -> "BaseParser": """Inits an empty Parser.""" self.Logger = logging.getLogger(log) self.Lines = [] @@ -50,7 +52,7 @@ def __init__(self, log: str="BaseParser") -> 'BaseParser': # For include files set the base root path # - def SetEdk2Path(self, pathobj: path_utilities.Edk2Path) -> 'BaseParser': + def SetEdk2Path(self, pathobj: path_utilities.Edk2Path) -> "BaseParser": """Sets the internal attribute Edk2PathUtil. !!! note @@ -88,7 +90,7 @@ def SetEdk2Path(self, pathobj: path_utilities.Edk2Path) -> 'BaseParser': self._Edk2PathUtil = pathobj return self - def SetBaseAbsPath(self, path: str) -> 'BaseParser': + def SetBaseAbsPath(self, path: str) -> "BaseParser": """Sets the attribute RootPath. Args: @@ -106,7 +108,7 @@ def _ConfigEdk2PathUtil(self) -> None: """Creates the path utility object based on the root path and package paths.""" self._Edk2PathUtil = path_utilities.Edk2Path(self.RootPath, self.PPs, error_on_invalid_pp=False) - def SetPackagePaths(self, pps: Optional[list[str]]=None) -> 'BaseParser': + def SetPackagePaths(self, pps: Optional[list[str]] = None) -> "BaseParser": """Sets the attribute PPs. Args: @@ -122,7 +124,7 @@ def SetPackagePaths(self, pps: Optional[list[str]]=None) -> 'BaseParser': self._ConfigEdk2PathUtil() return self - def SetInputVars(self, inputdict: dict) -> 'BaseParser': + def SetInputVars(self, inputdict: dict) -> "BaseParser": """Sets the attribute InputVars. Args: @@ -202,12 +204,12 @@ def ComputeResult(self, value: Union[str, int], cond: str, value2: Union[str, in ivalue = value ivalue2 = value2 if isinstance(value, str): - ivalue = value.strip("\"") + ivalue = value.strip('"') if isinstance(value2, str): - ivalue2 = value2.strip("\"") + ivalue2 = value2.strip('"') # convert it to interpretted value - if (cond.upper() == "IN"): + if cond.upper() == "IN": # strip quotes self.Logger.debug(f"{ivalue} in {ivalue2}") @@ -218,7 +220,7 @@ def ComputeResult(self, value: Union[str, int], cond: str, value2: Union[str, in except ValueError: pass try: - if (cond.lower() == "in"): + if cond.lower() == "in": ivalue2 = set(ivalue2.split()) else: ivalue2 = self.ConvertToInt(ivalue2) @@ -226,23 +228,24 @@ def ComputeResult(self, value: Union[str, int], cond: str, value2: Union[str, in pass # First check our boolean operators - if (cond.upper() == "OR"): + if cond.upper() == "OR": return ivalue or ivalue2 - if (cond.upper() == "AND"): + if cond.upper() == "AND": return ivalue and ivalue2 # check our truthyness - if (cond == "=="): + if cond == "==": # equal return (ivalue == ivalue2) or (value == value2) - elif (cond == "!="): + elif cond == "!=": # not equal return (ivalue != ivalue2) and (value != value2) # check to make sure we only have digits from here on out - if (isinstance(value, str) and value.upper() in ["TRUE", "FALSE"]) \ - or (isinstance(value, str) and value2.upper() in ["TRUE", "FALSE"]): + if (isinstance(value, str) and value.upper() in ["TRUE", "FALSE"]) or ( + isinstance(value, str) and value2.upper() in ["TRUE", "FALSE"] + ): self.Logger.error(f"Invalid comparison: {value} {cond} {value2}") self.Logger.debug(f"Invalid comparison: {value} {cond} {value2}") raise ValueError("Invalid comparison") @@ -257,17 +260,17 @@ def ComputeResult(self, value: Union[str, int], cond: str, value2: Union[str, in self.Logger.debug(f"{self.__class__}: Conditional: {value} {cond} {value2}") raise ValueError("Unknown value") - if (cond == "<"): - return (ivalue < ivalue2) + if cond == "<": + return ivalue < ivalue2 - elif (cond == "<="): - return (ivalue <= ivalue2) + elif cond == "<=": + return ivalue <= ivalue2 - elif (cond == ">"): - return (ivalue > ivalue2) + elif cond == ">": + return ivalue > ivalue2 - elif (cond == ">="): - return (ivalue >= ivalue2) + elif cond == ">=": + return ivalue >= ivalue2 else: self.Logger.error(f"{self.__class__}: Unknown conditional: {cond}") @@ -317,29 +320,28 @@ def PopConditional(self) -> bool: Returns (bool, bool): (value, already_true) """ - if (len(self.ConditionalStack) > 0): + if len(self.ConditionalStack) > 0: return self.ConditionalStack.pop() else: self.Logger.critical("Tried to pop an empty conditional stack. Line Number %d" % self.CurrentLine) return self.ConditionalStack.pop() # this should cause a crash but will give trace. - def _FindReplacementForToken(self, token: str, replace_if_not_found: bool=False) -> str: - + def _FindReplacementForToken(self, token: str, replace_if_not_found: bool = False) -> str: v = self.LocalVars.get(token) - if (v is None): + if v is None: v = self.InputVars.get(token) - if (v is None and replace_if_not_found): + if v is None and replace_if_not_found: v = self._MacroNotDefinedValue - elif (v is None): + elif v is None: return None - if (isinstance(v, bool)): + if isinstance(v, bool): v = "true" if v else "false" - if (isinstance(v, str) and (v.upper() == "TRUE" or v.upper() == "FALSE")): + if isinstance(v, str) and (v.upper() == "TRUE" or v.upper() == "FALSE"): v = v.upper() return str(v) @@ -368,12 +370,12 @@ def ReplaceVariables(self, line: str) -> str: # use line to avoid change by handling above rep = line.count("$") index = 0 - while (rep > 0): + while rep > 0: start = line.find("$(", index) end = line.find(")", start) - token = line[start + 2:end] - replacement_token = line[start:end + 1] + token = line[start + 2 : end] + replacement_token = line[start : end + 1] self.Logger.debug("Token is %s" % token) v = self._FindReplacementForToken(token, replace) if v is not None: @@ -398,12 +400,12 @@ def ProcessConditional(self, text: str) -> bool: tokens = tokens[0].split() + [tokens[1]] + tokens[2].split() else: tokens = text.split() - if (tokens[0].lower() == "!if"): + if tokens[0].lower() == "!if": result = self.EvaluateConditional(text) self.PushConditional(result, result) return True - elif (tokens[0].lower() == "!elseif"): + elif tokens[0].lower() == "!elseif": if not self.InActiveCode(): (_, already_been_true) = self.PopConditional() @@ -418,21 +420,21 @@ def ProcessConditional(self, text: str) -> bool: self.PushConditional(False, True) return True - elif (tokens[0].lower() == "!ifdef"): + elif tokens[0].lower() == "!ifdef": if len(tokens) != 2: self.Logger.error("!ifdef conditionals need to be formatted correctly (spaces between each token)") raise RuntimeError("Invalid conditional", text) self.PushConditional((tokens[1] != self._MacroNotDefinedValue)) return True - elif (tokens[0].lower() == "!ifndef"): + elif tokens[0].lower() == "!ifndef": if len(tokens) != 2: self.Logger.error("!ifdef conditionals need to be formatted correctly (spaces between each token)") raise RuntimeError("Invalid conditional", text) self.PushConditional((tokens[1] == self._MacroNotDefinedValue)) return True - elif (tokens[0].lower() == "!else"): + elif tokens[0].lower() == "!else": if len(tokens) != 1: self.Logger.error("!ifdef conditionals need to be formatted correctly (spaces between each token)") raise RuntimeError("Invalid conditional", text) @@ -447,7 +449,7 @@ def ProcessConditional(self, text: str) -> bool: self.PushConditional(True, True) return True - elif (tokens[0].lower() == "!endif"): + elif tokens[0].lower() == "!endif": if len(tokens) != 1: self.Logger.error("!ifdef conditionals need to be formatted correctly (spaces between each token)") raise RuntimeError("Invalid conditional", text) @@ -497,8 +499,10 @@ def EvaluateConditional(self, text: str) -> bool: operator1 = self.ConvertToInt(operator1_raw) result = not operator1 # grab what was before the operator and the operand, then squish it all together - new_expression = expression[:first_operand_index - 1] if first_operand_index > 1 else [] - new_expression += [result, ] + expression[first_operand_index + 1:] + new_expression = expression[: first_operand_index - 1] if first_operand_index > 1 else [] + new_expression += [ + result, + ] + expression[first_operand_index + 1 :] expression = new_expression else: if first_operand_index < 2: @@ -517,8 +521,10 @@ def EvaluateConditional(self, text: str) -> bool: if do_invert: result = not result # grab what was before the operator and the operand, then smoosh it all together - new_expression = expression[:first_operand_index - 2] if first_operand_index > 2 else [] - new_expression += [result, ] + expression[first_operand_index + 1:] + new_expression = expression[: first_operand_index - 2] if first_operand_index > 2 else [] + new_expression += [ + result, + ] + expression[first_operand_index + 1 :] expression = new_expression final = self.ConvertToInt(expression[0]) @@ -527,7 +533,7 @@ def EvaluateConditional(self, text: str) -> bool: return bool(final) @classmethod - def _TokenizeConditional(cls: 'BaseParser', text: str) -> str: + def _TokenizeConditional(cls: "BaseParser", text: str) -> str: """Takes in a string that has macros replaced.""" # TOKENIZER # first we create tokens @@ -540,17 +546,17 @@ def _TokenizeConditional(cls: 'BaseParser', text: str) -> str: mode = 0 tokens = [] for character in text: - if character == "\"" and len(token) == 0: + if character == '"' and len(token) == 0: mode = QUOTE_MODE - elif character == "\"" and mode == QUOTE_MODE: + elif character == '"' and mode == QUOTE_MODE: if len(token) > 0: - tokens.append(f"\"{token}\"") + tokens.append(f'"{token}"') token = "" mode = TEXT_MODE elif character == "$" and len(token) == 0: token += character mode = MACRO_MODE - elif character == ')' and mode == MACRO_MODE: + elif character == ")" and mode == MACRO_MODE: token += character tokens.append(token) token = "" @@ -576,12 +582,12 @@ def _TokenizeConditional(cls: 'BaseParser', text: str) -> str: elif character not in CONDITION_CHARACTERS and mode == CONDITION_MODE: if len(token) > 0: tokens.append(token) - token = character if character != " " else '' + token = character if character != " " else "" mode = TEXT_MODE elif character in CONDITION_CHARACTERS and mode == TEXT_MODE: if len(token) > 0: tokens.append(token) - token = '' + token = "" token = character mode = CONDITION_MODE else: @@ -628,7 +634,7 @@ def _TokenizeConditional(cls: 'BaseParser', text: str) -> str: return collapsed_tokens @classmethod - def _ConvertTokensToPostFix(cls: 'BaseParser', tokens: list[str]) -> list[str]: + def _ConvertTokensToPostFix(cls: "BaseParser", tokens: list[str]) -> list[str]: # convert infix into post fix stack = ["("] tokens.append(")") # add an extra parathesis @@ -641,14 +647,14 @@ def _ConvertTokensToPostFix(cls: 'BaseParser', tokens: list[str]) -> list[str]: # pop the stack and print the operators until you see a left parenthesis. # Discard the pair of parentheses. elif token == ")": - while len(stack) > 0 and stack[-1] != '(': + while len(stack) > 0 and stack[-1] != "(": expression.append(stack.pop()) stack.pop() # pop the last ( # If this isn't a operator ignore it elif not cls._IsOperator(token): expression.append(token) # If the stack is empty or contains a left parenthesis on top, push the incoming operator onto the stack. - elif len(stack) == 0 or stack[-1] == '(': + elif len(stack) == 0 or stack[-1] == "(": stack.append(token) # If the incoming symbol has higher precedence than the top of the stack, push it on the stack. elif len(stack) == 0 or cls._GetOperatorPrecedence(token) > cls._GetOperatorPrecedence(stack[-1]): @@ -674,7 +680,7 @@ def _ConvertTokensToPostFix(cls: 'BaseParser', tokens: list[str]) -> list[str]: return expression @classmethod - def _IsOperator(cls: 'BaseParser', token: str) -> bool: + def _IsOperator(cls: "BaseParser", token: str) -> bool: if not isinstance(token, str): return False if token.startswith("!+"): @@ -684,7 +690,7 @@ def _IsOperator(cls: 'BaseParser', token: str) -> bool: return token in cls.operators @classmethod - def _GetOperatorPrecedence(cls: 'BaseParser', token: str) -> int: + def _GetOperatorPrecedence(cls: "BaseParser", token: str) -> int: if not cls._IsOperator(token): return -1 if token == "(" or token == ")": @@ -702,7 +708,7 @@ def InActiveCode(self) -> bool: (bool): result of the state of the conditional you are in. """ ret = True - for (a, _) in self.ConditionalStack: + for a, _ in self.ConditionalStack: if not a: ret = False break @@ -721,7 +727,7 @@ def IsGuidString(self, line: str) -> str: NOTE: format = { 0xD3B36F2C, 0xD551, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }} Will return true if the the line has """ - if (line.count("{") == 2 and line.count("}") == 2 and line.count(",") == 10 and line.count("=") == 1): + if line.count("{") == 2 and line.count("}") == 2 and line.count(",") == 10 and line.count("=") == 1: return True return False @@ -738,63 +744,64 @@ def ParseGuid(self, line: str) -> str: Raises: (RuntimeError): if missing any of the 11 parts, or it isn't long enough. """ - entries = line.lstrip(' {').rstrip(' }').split(',') + entries = line.lstrip(" {").rstrip(" }").split(",") if len(entries) != 11: raise RuntimeError( - f"Invalid GUID found {line}. We are missing some parts since we only found: {len(entries)}") - gu = entries[0].lstrip(' 0').lstrip('x').strip() + f"Invalid GUID found {line}. We are missing some parts since we only found: {len(entries)}" + ) + gu = entries[0].lstrip(" 0").lstrip("x").strip() # pad front until 8 chars - while (len(gu) < 8): + while len(gu) < 8: gu = "0" + gu - gut = entries[1].lstrip(' 0').lstrip('x').strip() - while (len(gut) < 4): + gut = entries[1].lstrip(" 0").lstrip("x").strip() + while len(gut) < 4: gut = "0" + gut gu = gu + "-" + gut - gut = entries[2].lstrip(' 0').lstrip('x').strip() - while (len(gut) < 4): + gut = entries[2].lstrip(" 0").lstrip("x").strip() + while len(gut) < 4: gut = "0" + gut gu = gu + "-" + gut # strip off extra { - gut = entries[3].lstrip(' { 0').lstrip('x').strip() - while (len(gut) < 2): + gut = entries[3].lstrip(" { 0").lstrip("x").strip() + while len(gut) < 2: gut = "0" + gut gu = gu + "-" + gut - gut = entries[4].lstrip(' 0').lstrip('x').strip() - while (len(gut) < 2): + gut = entries[4].lstrip(" 0").lstrip("x").strip() + while len(gut) < 2: gut = "0" + gut gu = gu + gut - gut = entries[5].lstrip(' 0').lstrip('x').strip() - while (len(gut) < 2): + gut = entries[5].lstrip(" 0").lstrip("x").strip() + while len(gut) < 2: gut = "0" + gut gu = gu + "-" + gut - gut = entries[6].lstrip(' 0').lstrip('x').strip() - while (len(gut) < 2): + gut = entries[6].lstrip(" 0").lstrip("x").strip() + while len(gut) < 2: gut = "0" + gut gu = gu + gut - gut = entries[7].lstrip(' 0').lstrip('x').strip() - while (len(gut) < 2): + gut = entries[7].lstrip(" 0").lstrip("x").strip() + while len(gut) < 2: gut = "0" + gut gu = gu + gut - gut = entries[8].lstrip(' 0').lstrip('x').strip() - while (len(gut) < 2): + gut = entries[8].lstrip(" 0").lstrip("x").strip() + while len(gut) < 2: gut = "0" + gut gu = gu + gut - gut = entries[9].lstrip(' 0').lstrip('x').strip() - while (len(gut) < 2): + gut = entries[9].lstrip(" 0").lstrip("x").strip() + while len(gut) < 2: gut = "0" + gut gu = gu + gut - gut = entries[10].split()[0].lstrip(' 0').lstrip('x').rstrip(' } ').strip() - while (len(gut) < 2): + gut = entries[10].split()[0].lstrip(" 0").lstrip("x").rstrip(" } ").strip() + while len(gut) < 2: gut = "0" + gut gu = gu + gut @@ -809,15 +816,15 @@ def ParseGuid(self, line: str) -> str: def ResetParserState(self) -> None: """Resets the state of the parser.""" self.ConditionalStack = [] - self.CurrentSection = '' - self.CurrentFullSection = '' + self.CurrentSection = "" + self.CurrentFullSection = "" self.Parsed = False class HashFileParser(BaseParser): """Base class for Edk2 build files that use # for comments.""" - def __init__(self, log: str) -> 'HashFileParser': + def __init__(self, log: str) -> "HashFileParser": """Inits an empty Parser for files that use # for comments..""" BaseParser.__init__(self, log) @@ -843,16 +850,16 @@ def StripComment(self, line: str) -> str: elif char == quote_char: inside_quotes = False quote_char = None - elif char == '#' and not inside_quotes: + elif char == "#" and not inside_quotes: break - elif char == '\\' and not escaped: + elif char == "\\" and not escaped: escaped = True else: escaped = False result.append(char) - return ''.join(result).rstrip() + return "".join(result).rstrip() def ParseNewSection(self, line: str) -> tuple[bool, str]: """Parses a new section line. @@ -860,7 +867,7 @@ def ParseNewSection(self, line: str) -> tuple[bool, str]: Args: line (str): line representing a new section. """ - if (line.count("[") == 1 and line.count("]") == 1): # new section + if line.count("[") == 1 and line.count("]") == 1: # new section section = line.strip().lstrip("[").split(".")[0].split(",")[0].rstrip("]").strip() self.CurrentFullSection = line.strip().lstrip("[").split(",")[0].rstrip("]").strip() return (True, section) diff --git a/edk2toollib/uefi/edk2/parsers/buildreport_parser.py b/edk2toollib/uefi/edk2/parsers/buildreport_parser.py index ce68e176..b70abf8f 100644 --- a/edk2toollib/uefi/edk2/parsers/buildreport_parser.py +++ b/edk2toollib/uefi/edk2/parsers/buildreport_parser.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Code to help parse an Edk2 Build Report.""" + import logging import os from enum import Enum @@ -29,7 +30,8 @@ class ModuleSummary(object): PackagePathList (list): list of package paths FvName (str): Name of Fv """ - def __init__(self, content: str, ws: str, packagepatahlist: list, pathconverter: pu.Edk2Path) -> 'ModuleSummary': + + def __init__(self, content: str, ws: str, packagepatahlist: list, pathconverter: pu.Edk2Path) -> "ModuleSummary": """Inits an empty Module Summary Object.""" self._RawContent = content self.Guid = "" @@ -55,35 +57,40 @@ def Parse(self) -> None: i = 0 try: - while i < len(self._RawContent): line = self._RawContent[i].strip() # parse start and end - if line == ">----------------------------------------------------------------------------------------------------------------------<": # noqa: E501 + if ( + line + == ">----------------------------------------------------------------------------------------------------------------------<" + ): # noqa: E501 nextLineSection = True - elif line == "<---------------------------------------------------------------------------------------------------------------------->": # noqa: E501 + elif ( + line + == "<---------------------------------------------------------------------------------------------------------------------->" + ): # noqa: E501 inPcdSection = False inLibSection = False inDepSection = False nextLineSection = False # parse section header - elif (nextLineSection): + elif nextLineSection: nextLineSection = False - if (line == "Library"): + if line == "Library": inLibSection = True i += 1 # add additional line to skip the dashed line - elif (line == "PCD"): + elif line == "PCD": inPcdSection = True i += 1 # add additional line to skip the dashed line - elif (line == "Final Dependency Expression (DEPEX) Instructions"): + elif line == "Final Dependency Expression (DEPEX) Instructions": inDepSection = True i += 1 # add additional line to skip the dashed line - elif (line == "Dependency Expression (DEPEX) from INF"): + elif line == "Dependency Expression (DEPEX) from INF": # For some reason, "Final Dependency Expression (DEPEX) Instructions" does not exist # For all modules, so we need to check for this as well. inDepSection = True @@ -96,11 +103,11 @@ def Parse(self) -> None: # Normal section parsing else: - if (inLibSection): + if inLibSection: logging.debug("InLibSection: %s" % line) # get the whole statement library class statement templine = line.strip() - while ('}' not in templine): + while "}" not in templine: i += 1 templine += self._RawContent[i].strip() @@ -108,46 +115,46 @@ def Parse(self) -> None: # first is the library instance INF # second is the library class - lib_class = templine.partition('{')[2].partition('}')[0].partition(':')[0].strip() - lib_instance = templine.partition('{')[0].strip() + lib_class = templine.partition("{")[2].partition("}")[0].partition(":")[0].strip() + lib_instance = templine.partition("{")[0].strip() # Take absolute path and convert to EDK build path RelativePath = self.pathConverter.GetEdk2RelativePathFromAbsolutePath(lib_instance) - if (RelativePath is not None): + if RelativePath is not None: self.Libraries[lib_class] = RelativePath else: self.Libraries[lib_class] = lib_instance i += 1 continue - elif (inPcdSection): + elif inPcdSection: # this is the namespace token line - if (len(line.split()) == 1): + if len(line.split()) == 1: tokenspace = line # this is the main line of the PCD value - elif (line.count("=") == 1 and line.count(":") == 1): - while (line.count("\"") % 2) != 0: + elif line.count("=") == 1 and line.count(":") == 1: + while (line.count('"') % 2) != 0: i += 1 line += " " + self._RawContent[i].rstrip() - while (line.count('{') != line.count('}')): + while line.count("{") != line.count("}"): i += 1 line += " " + self._RawContent[i].rstrip() - token = line.partition('=')[2] - if (line.partition(':')[0].split() == []): + token = line.partition("=")[2] + if line.partition(":")[0].split() == []: token2 = "" else: - token2 = line.partition(':')[0].split()[-1] + token2 = line.partition(":")[0].split()[-1] self.PCDs[tokenspace + "." + token2] = token.strip() # this is the secondary lines of PCD values showing Defaults elif line.count(":") == 0 and line.count("=") == 1: - while (line.count("\"") % 2) != 0: + while (line.count('"') % 2) != 0: i += 1 line += self._RawContent[i].rstrip() - elif (inDepSection): + elif inDepSection: if line == "Dependency Expression (DEPEX) from INF": inOverallDepex = True elif line.startswith("-----"): @@ -158,25 +165,25 @@ def Parse(self) -> None: else: # not in section...Must be header section - line_partitioned = line.partition(':') - if (line_partitioned[2] == ""): + line_partitioned = line.partition(":") + if line_partitioned[2] == "": pass # not a name: value pair else: key = line_partitioned[0].strip().lower() value = line_partitioned[2].strip() - if (key == "module name"): + if key == "module name": logging.debug("Parsing Mod: %s" % value) self.Name = value - elif (key == "module inf path"): - while (".inf" not in value.lower()): + elif key == "module inf path": + while ".inf" not in value.lower(): i += 1 value += self._RawContent[i].strip() self.InfPath = value.replace("\\", "/") - elif (key == "file guid"): + elif key == "file guid": self.Guid = value - elif (key == "driver type"): + elif key == "driver type": value = value.strip() - self.Type = value[value.index('(') + 1:-1] + self.Type = value[value.index("(") + 1 : -1] i += 1 except Exception: @@ -199,14 +206,16 @@ class BuildReport(object): ProtectedWords (dict): Dict of protected words PathConverter (Edk2Path): path utilities """ + class RegionTypes(Enum): """Enum for different Region Types.""" - PCD = 'PCD' - FD = 'FD' - MODULE = 'MODULE' - UNKNOWN = 'UNKNOWN' - def __init__(self, filepath: str, ws: str, packagepathcsv: str, protectedWordsDict: dict) -> 'RegionTypes': + PCD = "PCD" + FD = "FD" + MODULE = "MODULE" + UNKNOWN = "UNKNOWN" + + def __init__(self, filepath: str, ws: str, packagepathcsv: str, protectedWordsDict: dict) -> "RegionTypes": """Inits an empty BuildReport object.""" self.PlatformName = "" self.DscPath = "" @@ -220,7 +229,7 @@ def __init__(self, filepath: str, ws: str, packagepathcsv: str, protectedWordsDi self.PackagePathList = [] for a in packagepathcsv.split(","): a = a.strip() - if (len(a) > 0): + if len(a) > 0: self.PackagePathList.append(a) self.ProtectedWords = protectedWordsDict self.PathConverter = pu.Edk2Path(self.Workspace, self.PackagePathList) @@ -234,7 +243,7 @@ def BasicParse(self) -> None: Gets the layout, lists, and dictionaries setup. """ - if (not os.path.isfile(self.ReportFile)): + if not os.path.isfile(self.ReportFile): raise Exception("Report File path invalid!") # read report @@ -244,7 +253,7 @@ def BasicParse(self) -> None: # # replace protected words # - for (k, v) in self.ProtectedWords.items(): + for k, v in self.ProtectedWords.items(): self._ReportContents = [x.replace(k, v) for x in self._ReportContents] logging.debug("Report File is: %s" % self.ReportFile) @@ -256,7 +265,7 @@ def BasicParse(self) -> None: # fail but it doesn't seem critical # linenum = self._GetNextRegionStart(0) - while (linenum is not None): + while linenum is not None: start = linenum end = self._GetEndOfRegion(start) type = self._GetRegionType(start) @@ -271,38 +280,38 @@ def BasicParse(self) -> None: # for n in range(self._Regions[0][1]): # loop thru from 0 to start of first region line = self._ReportContents[n].strip() - line_partitioned = line.partition(':') - if (line_partitioned[2] == ""): + line_partitioned = line.partition(":") + if line_partitioned[2] == "": continue key = line_partitioned[0].strip().lower() value = line_partitioned[2].strip() - if (key == "platform name"): + if key == "platform name": self.PlatformName = value - elif (key == "platform dsc path"): + elif key == "platform dsc path": self.DscPath = value - elif (key == "output path"): + elif key == "output path": self.BuildOutputDir = value # # now for each module summary # parse it for r in self._Regions: - if (r[0] == BuildReport.RegionTypes.MODULE): - mod = ModuleSummary(self._ReportContents[r[1]:r[2]], - self.Workspace, self.PackagePathList, - self.PathConverter) + if r[0] == BuildReport.RegionTypes.MODULE: + mod = ModuleSummary( + self._ReportContents[r[1] : r[2]], self.Workspace, self.PackagePathList, self.PathConverter + ) mod.Parse() self.Modules[mod.Guid] = mod # now that all modules are parsed lets parse the FD region so we can get the FV name for each module for r in self._Regions: # if FD region parse out all INFs in the all of the flash - if (r[0] == BuildReport.RegionTypes.FD): - self._ParseFdRegionForModules(self._ReportContents[r[1]:r[2]]) + if r[0] == BuildReport.RegionTypes.FD: + self._ParseFdRegionForModules(self._ReportContents[r[1] : r[2]]) - def FindComponentByInfPath(self, InfPath: str) -> Optional['ModuleSummary']: + def FindComponentByInfPath(self, InfPath: str) -> Optional["ModuleSummary"]: """Attempts to find the Component the Inf is apart of. Args: @@ -312,10 +321,10 @@ def FindComponentByInfPath(self, InfPath: str) -> Optional['ModuleSummary']: (ModuleSummary): Module if found (None): If not found """ - for (k, v) in self.Modules.items(): + for k, v in self.Modules.items(): if os.path.isabs(v.InfPath): v.InfPath = self.PathConverter.GetEdk2RelativePathFromAbsolutePath(v.InfPath) - if (v.InfPath.lower() == InfPath.lower()): + if v.InfPath.lower() == InfPath.lower(): logging.debug("Found Module by InfPath: %s" % InfPath) return v @@ -331,19 +340,19 @@ def _ParseFdRegionForModules(self, rawcontents: str) -> None: while index < len(rawcontents): a = rawcontents[index] tokens = a.split() - if a.startswith("0x") and (len(tokens) == 3) and (a.count('(') == 1): - if ".inf" not in a.lower() or (a.count('(') != a.count(")")): + if a.startswith("0x") and (len(tokens) == 3) and (a.count("(") == 1): + if ".inf" not in a.lower() or (a.count("(") != a.count(")")): a = a + rawcontents[index + 1].strip() index += 1 tokens = a.split() - i = a.split()[2].strip().strip('()') + i = a.split()[2].strip().strip("()") logging.debug("Found INF in FV Region: " + i) # Take absolute path and convert to EDK build path RelativePath = self.PathConverter.GetEdk2RelativePathFromAbsolutePath(i) - if (RelativePath is not None): + if RelativePath is not None: comp = self.FindComponentByInfPath(RelativePath) if comp is not None: comp.FvName = FvName @@ -365,8 +374,11 @@ def _ParseFdRegionForModules(self, rawcontents: str) -> None: # def _GetNextRegionStart(self, number: int) -> Optional[int]: lineNumber = number - while (lineNumber < len(self._ReportContents)): - if self._ReportContents[lineNumber] == ">======================================================================================================================<": # noqa: E501 + while lineNumber < len(self._ReportContents): + if ( + self._ReportContents[lineNumber] + == ">======================================================================================================================<" + ): # noqa: E501 return lineNumber + 1 lineNumber += 1 logging.debug("Failed to find a Start Next Region after lineNumber: %d" % number) @@ -378,8 +390,11 @@ def _GetNextRegionStart(self, number: int) -> Optional[int]: # def _GetEndOfRegion(self, number: int) -> Optional[int]: lineNumber = number - while (lineNumber < len(self._ReportContents)): - if self._ReportContents[lineNumber] == "<======================================================================================================================>": # noqa: E501 + while lineNumber < len(self._ReportContents): + if ( + self._ReportContents[lineNumber] + == "<======================================================================================================================>" + ): # noqa: E501 return lineNumber - 1 lineNumber += 1 @@ -387,13 +402,13 @@ def _GetEndOfRegion(self, number: int) -> Optional[int]: # didn't find new region return None - def _GetRegionType(self, lineNumber: int) -> 'BuildReport.RegionTypes': + def _GetRegionType(self, lineNumber: int) -> "BuildReport.RegionTypes": line = self._ReportContents[lineNumber].strip() - if (line == "Firmware Device (FD)"): + if line == "Firmware Device (FD)": return BuildReport.RegionTypes.FD - elif (line == "Platform Configuration Database Report"): + elif line == "Platform Configuration Database Report": return BuildReport.RegionTypes.PCD - elif (line == "Module Summary"): + elif line == "Module Summary": return BuildReport.RegionTypes.MODULE else: return BuildReport.RegionTypes.UNKNOWN diff --git a/edk2toollib/uefi/edk2/parsers/dec_parser.py b/edk2toollib/uefi/edk2/parsers/dec_parser.py index 2f0b86a7..5ad2fcb8 100644 --- a/edk2toollib/uefi/edk2/parsers/dec_parser.py +++ b/edk2toollib/uefi/edk2/parsers/dec_parser.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Code to help parse DEC files.""" + import os import re from typing import IO @@ -14,14 +15,15 @@ from edk2toollib.uefi.edk2.parsers.guid_parser import GuidParser -class LibraryClassDeclarationEntry(): +class LibraryClassDeclarationEntry: """Object representing a Library Class Declaration Entry.""" - def __init__(self, packagename: str, rawtext: str = None) -> 'LibraryClassDeclarationEntry': + + def __init__(self, packagename: str, rawtext: str = None) -> "LibraryClassDeclarationEntry": """Init a library Class Declaration Entry.""" self.path = "" self.name = "" self.package_name = packagename - if (rawtext is not None): + if rawtext is not None: self._parse(rawtext) def _parse(self, rawtext: str) -> None: @@ -39,7 +41,7 @@ def _parse(self, rawtext: str) -> None: self.path = t[2].strip() -class GuidedDeclarationEntry(): +class GuidedDeclarationEntry: """A baseclass for declaration types that have a name and guid. Attributes: @@ -48,17 +50,18 @@ class GuidedDeclarationEntry(): guid (uuid.UUID): guid package_name (str): packagename """ + PROTOCOL = 1 PPI = 2 GUID = 3 - def __init__(self, packagename: str, rawtext: str = None) -> 'GuidedDeclarationEntry': + def __init__(self, packagename: str, rawtext: str = None) -> "GuidedDeclarationEntry": """Init a protocol/Ppi/or Guid declaration entry.""" self.name = "" self.guidstring = "" self.guid = None self.package_name = packagename - if (rawtext is not None): + if rawtext is not None: self._parse(rawtext) def _parse(self, rawtext: str) -> None: @@ -71,13 +74,14 @@ def _parse(self, rawtext: str) -> None: self.name = t[0].strip() self.guidstring = t[2].strip() self.guid = GuidParser.uuid_from_guidstring(self.guidstring) - if (self.guid is None): + if self.guid is None: raise ValueError("Could not parse guid") class ProtocolDeclarationEntry(GuidedDeclarationEntry): """Object representing a Protocol Declaration Entry.""" - def __init__(self, packagename: str, rawtext: str = None) -> 'ProtocolDeclarationEntry': + + def __init__(self, packagename: str, rawtext: str = None) -> "ProtocolDeclarationEntry": """Init a protocol declaration entry.""" super().__init__(packagename, rawtext) self.type = GuidedDeclarationEntry.PROTOCOL @@ -85,7 +89,8 @@ def __init__(self, packagename: str, rawtext: str = None) -> 'ProtocolDeclaratio class PpiDeclarationEntry(GuidedDeclarationEntry): """Object representing a Ppi Declaration Entry.""" - def __init__(self, packagename: str, rawtext: str = None) -> 'GuidedDeclarationEntry': + + def __init__(self, packagename: str, rawtext: str = None) -> "GuidedDeclarationEntry": """Init a Ppi declaration entry.""" super().__init__(packagename, rawtext) self.type = GuidedDeclarationEntry.PPI @@ -93,13 +98,14 @@ def __init__(self, packagename: str, rawtext: str = None) -> 'GuidedDeclarationE class GuidDeclarationEntry(GuidedDeclarationEntry): """Object representing a Guid Declaration Entry.""" - def __init__(self, packagename: str, rawtext: str = None) -> 'GuidDeclarationEntry': + + def __init__(self, packagename: str, rawtext: str = None) -> "GuidDeclarationEntry": """Init a Ppi declaration entry.""" super().__init__(packagename, rawtext) self.type = GuidedDeclarationEntry.GUID -class PcdDeclarationEntry(): +class PcdDeclarationEntry: """Object representing a Pcd Delcaration Entry. Attributes: @@ -110,7 +116,8 @@ class PcdDeclarationEntry(): id (str): id package_name: package name """ - def __init__(self, packagename: str, rawtext: str = None) -> 'PcdDeclarationEntry': + + def __init__(self, packagename: str, rawtext: str = None) -> "PcdDeclarationEntry": """Creates a PCD Declaration Entry for one PCD.""" self.token_space_name = "" self.name = "" @@ -118,7 +125,7 @@ def __init__(self, packagename: str, rawtext: str = None) -> 'PcdDeclarationEntr self.type = "" self.id = "" self.package_name = packagename - if (rawtext is not None): + if rawtext is not None: self._parse(rawtext) def _parse(self, rawtext: str) -> None: @@ -131,15 +138,15 @@ def _parse(self, rawtext: str) -> None: op = re.split(pattern, sp[2]) # if it's 2 long, we need to check that it's a structured PCD - if (len(op) == 2 and op[0].count(".") > 0): + if len(op) == 2 and op[0].count(".") > 0: pass # otherwise it needs at least 4 parts - elif (len(op) < 4): + elif len(op) < 4: raise Exception(f"Too few parts: {op}") # but also less than 5 - elif (len(op) > 5): + elif len(op) > 5: raise Exception(f"Too many parts: {rawtext}") - elif (len(op) == 5 and op[4].strip() != '{'): + elif len(op) == 5 and op[4].strip() != "{": raise Exception(f"Too many parts: {rawtext}") self.name = op[0].strip() @@ -166,9 +173,9 @@ class DecParser(HashFileParser): Path (str): path to the DEC file """ - def __init__(self) -> 'DecParser': + def __init__(self) -> "DecParser": """Init an empty Dec Parser.""" - HashFileParser.__init__(self, 'DecParser') + HashFileParser.__init__(self, "DecParser") self.Lines = [] self.Parsed = False self.Dict = {} @@ -195,22 +202,22 @@ def _Parse(self) -> None: for line in self.Lines: sline = self.StripComment(line) - if (sline is None or len(sline) < 1): + if sline is None or len(sline) < 1: continue if InDefinesSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InDefinesSection = False else: if sline.count("=") == 1: - tokens = sline.split('=', 1) + tokens = sline.split("=", 1) self.Dict[tokens[0].strip()] = tokens[1].strip() - if (self.PackageName is None and tokens[0].strip() == "PACKAGE_NAME"): + if self.PackageName is None and tokens[0].strip() == "PACKAGE_NAME": self.PackageName = self.Dict["PACKAGE_NAME"] continue elif InLibraryClassSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InLibraryClassSection = False else: t = LibraryClassDeclarationEntry(self.PackageName, sline) @@ -218,7 +225,7 @@ def _Parse(self) -> None: continue elif InProtocolsSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InProtocolsSection = False else: t = ProtocolDeclarationEntry(self.PackageName, sline) @@ -226,7 +233,7 @@ def _Parse(self) -> None: continue elif InGuidsSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InGuidsSection = False else: t = GuidDeclarationEntry(self.PackageName, sline) @@ -234,28 +241,28 @@ def _Parse(self) -> None: continue elif InPcdSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InPcdSection = False - elif sline.strip()[0] == '}': + elif sline.strip()[0] == "}": InStructuredPcdDeclaration = False else: if InStructuredPcdDeclaration: continue t = PcdDeclarationEntry(self.PackageName, sline) self.Pcds.append(t) - if sline.rstrip()[-1] == '{': + if sline.rstrip()[-1] == "{": InStructuredPcdDeclaration = True continue elif InIncludesSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InIncludesSection = False else: self.IncludePaths.append(sline.strip()) continue elif InPPISection: - if (sline.strip()[0] == '['): + if sline.strip()[0] == "[": InPPISection = False else: t = PpiDeclarationEntry(self.PackageName, sline) @@ -263,25 +270,25 @@ def _Parse(self) -> None: continue # check for different sections - if sline.strip().lower().startswith('[defines'): + if sline.strip().lower().startswith("[defines"): InDefinesSection = True - elif sline.strip().lower().startswith('[libraryclasses'): + elif sline.strip().lower().startswith("[libraryclasses"): InLibraryClassSection = True - elif sline.strip().lower().startswith('[protocols'): + elif sline.strip().lower().startswith("[protocols"): InProtocolsSection = True - elif sline.strip().lower().startswith('[guids'): + elif sline.strip().lower().startswith("[guids"): InGuidsSection = True - elif sline.strip().lower().startswith('[ppis'): + elif sline.strip().lower().startswith("[ppis"): InPPISection = True - elif sline.strip().lower().startswith('[pcd'): + elif sline.strip().lower().startswith("[pcd"): InPcdSection = True - elif sline.strip().lower().startswith('[includes'): + elif sline.strip().lower().startswith("[includes"): InIncludesSection = True self.Parsed = True @@ -304,7 +311,7 @@ def ParseFile(self, filepath: str) -> None: relative to your CWD """ self.Logger.debug("Parsing file: %s" % filepath) - if (not os.path.isabs(filepath)): + if not os.path.isabs(filepath): fp = self.FindPath(filepath) else: fp = filepath diff --git a/edk2toollib/uefi/edk2/parsers/dsc_parser.py b/edk2toollib/uefi/edk2/parsers/dsc_parser.py index bddbb868..304e6d36 100644 --- a/edk2toollib/uefi/edk2/parsers/dsc_parser.py +++ b/edk2toollib/uefi/edk2/parsers/dsc_parser.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Code to help parse DSC files.""" + import logging import os import re @@ -35,14 +36,15 @@ class DscParser(HashFileParser): in the scope of "common", but one filters to only PEI (MyLib| PEI_CORE) and the other filters to PEIM (MyLib| PEIM). """ + SECTION_LIBRARY = "libraryclasses" SECTION_COMPONENT = "components" SECTION_REGEX = re.compile(r"\[(.*)\]") OVERRIDE_REGEX = re.compile(r"\<(.*)\>") - def __init__(self) -> 'HashFileParser': + def __init__(self) -> "HashFileParser": """Init an empty Parser.""" - super(DscParser, self).__init__('DscParser') + super(DscParser, self).__init__("DscParser") self.SixMods = [] self.SixModsEnhanced = [] self.ThreeMods = [] @@ -67,13 +69,13 @@ def ReplacePcds(self, line: str) -> str: line = line.replace(tokens[1], self.PcdValueDict[tokens[1]]) return line - def __ParseLine(self, Line: str, file_name: Optional[str]=None, lineno: int=None) -> tuple: + def __ParseLine(self, Line: str, file_name: Optional[str] = None, lineno: int = None) -> tuple: line_stripped = self.StripComment(Line).strip() - if (len(line_stripped) < 1): + if len(line_stripped) < 1: return ("", [], None) line_stripped = self.ReplacePcds(line_stripped) line_resolved = self.ReplaceVariables(line_stripped) - if (self.ProcessConditional(line_resolved)): + if self.ProcessConditional(line_resolved): # was a conditional # Other parser returns line_resolved, []. Need to figure out which is right return ("", [], None) @@ -81,11 +83,11 @@ def __ParseLine(self, Line: str, file_name: Optional[str]=None, lineno: int=None # not conditional keep processing # check if conditional is active - if (not self.InActiveCode()): + if not self.InActiveCode(): return ("", [], None) # check for include file and import lines from file - if (line_resolved.strip().lower().startswith("!include")): + if line_resolved.strip().lower().startswith("!include"): # include line. tokens = line_resolved.split() include_file = tokens[1] @@ -101,27 +103,27 @@ def __ParseLine(self, Line: str, file_name: Optional[str]=None, lineno: int=None # check for new section (IsNew, Section) = self.ParseNewSection(line_resolved) - if (IsNew): + if IsNew: self.CurrentSection = Section.upper() self.Logger.debug("New Section: %s" % self.CurrentSection) self.Logger.debug("FullSection: %s" % self.CurrentFullSection) return (line_resolved, [], None) # process line in x64 components - if (self.CurrentFullSection.upper() == "COMPONENTS.X64"): - if (self.ParsingInBuildOption > 0): - if (".inf" in line_resolved.lower()): + if self.CurrentFullSection.upper() == "COMPONENTS.X64": + if self.ParsingInBuildOption > 0: + if ".inf" in line_resolved.lower(): p = self.ParseInfPathLib(line_resolved) self.Libs.append(p) self.Logger.debug("Found Library in a 64bit BuildOptions Section: %s" % p) elif self.RegisterPcds(line_resolved): self.Logger.debug("Found a Pcd in a 64bit Module Override section") else: - if (".inf" in line_resolved.lower()): + if ".inf" in line_resolved.lower(): p = self.ParseInfPathMod(line_resolved) self.SixMods.append(p) if file_name is not None and lineno is not None: - self.SixModsEnhanced.append({'file': os.path.normpath(file_name), 'lineno': lineno, 'data': p}) + self.SixModsEnhanced.append({"file": os.path.normpath(file_name), "lineno": lineno, "data": p}) self.Logger.debug("Found 64bit Module: %s" % p) self.ParsingInBuildOption = self.ParsingInBuildOption + line_resolved.count("{") @@ -129,24 +131,25 @@ def __ParseLine(self, Line: str, file_name: Optional[str]=None, lineno: int=None return (line_resolved, [], None) # process line in ia32 components - elif (self.CurrentFullSection.upper() == "COMPONENTS.IA32"): - if (self.ParsingInBuildOption > 0): - if (".inf" in line_resolved.lower()): + elif self.CurrentFullSection.upper() == "COMPONENTS.IA32": + if self.ParsingInBuildOption > 0: + if ".inf" in line_resolved.lower(): p = self.ParseInfPathLib(line_resolved) self.Libs.append(p) if file_name is not None and lineno is not None: - self.LibsEnhanced.append({'file': os.path.normpath(file_name), 'lineno': lineno, 'data': p}) + self.LibsEnhanced.append({"file": os.path.normpath(file_name), "lineno": lineno, "data": p}) self.Logger.debug("Found Library in a 32bit BuildOptions Section: %s" % p) elif self.RegisterPcds(line_resolved): self.Logger.debug("Found a Pcd in a 32bit Module Override section") else: - if (".inf" in line_resolved.lower()): + if ".inf" in line_resolved.lower(): p = self.ParseInfPathMod(line_resolved) self.ThreeMods.append(p) if file_name is not None and lineno is not None: - self.ThreeModsEnhanced.append({'file': os.path.normpath(file_name), - 'lineno': lineno, 'data': p}) + self.ThreeModsEnhanced.append( + {"file": os.path.normpath(file_name), "lineno": lineno, "data": p} + ) self.Logger.debug("Found 32bit Module: %s" % p) self.ParsingInBuildOption = self.ParsingInBuildOption + line_resolved.count("{") @@ -154,9 +157,9 @@ def __ParseLine(self, Line: str, file_name: Optional[str]=None, lineno: int=None return (line_resolved, [], None) # process line in other components - elif ("COMPONENTS" in self.CurrentFullSection.upper()): - if (self.ParsingInBuildOption > 0): - if (".inf" in line_resolved.lower()): + elif "COMPONENTS" in self.CurrentFullSection.upper(): + if self.ParsingInBuildOption > 0: + if ".inf" in line_resolved.lower(): p = self.ParseInfPathLib(line_resolved) self.Libs.append(p) self.Logger.debug("Found Library in a BuildOptions Section: %s" % p) @@ -164,7 +167,7 @@ def __ParseLine(self, Line: str, file_name: Optional[str]=None, lineno: int=None self.Logger.debug("Found a Pcd in a Module Override section") else: - if (".inf" in line_resolved.lower()): + if ".inf" in line_resolved.lower(): p = self.ParseInfPathMod(line_resolved) self.OtherMods.append(p) self.Logger.debug("Found Module: %s" % p) @@ -174,14 +177,14 @@ def __ParseLine(self, Line: str, file_name: Optional[str]=None, lineno: int=None return (line_resolved, [], None) # process line in library class section (don't use full name) - elif (self.CurrentSection.upper() == "LIBRARYCLASSES"): - if (".inf" in line_resolved.lower()): + elif self.CurrentSection.upper() == "LIBRARYCLASSES": + if ".inf" in line_resolved.lower(): p = self.ParseInfPathLib(line_resolved) self.Libs.append(p) self.Logger.debug("Found Library in Library Class Section: %s" % p) return (line_resolved, [], None) # process line in PCD section - elif (self.CurrentSection.upper().startswith("PCDS")): + elif self.CurrentSection.upper().startswith("PCDS"): if self.RegisterPcds(line_resolved): self.Logger.debug("Found a Pcd in a PCD section") return (line_resolved, [], None) @@ -190,14 +193,14 @@ def __ParseLine(self, Line: str, file_name: Optional[str]=None, lineno: int=None def __ParseDefineLine(self, Line: str) -> tuple: line_stripped = self.StripComment(Line).strip() - if (len(line_stripped) < 1): + if len(line_stripped) < 1: return ("", []) # this line needs to be here to resolve any symbols inside the !include lines, if any self.RegisterPcds(line_stripped) line_stripped = self.ReplacePcds(line_stripped) line_resolved = self.ReplaceVariables(line_stripped) - if (self.ProcessConditional(line_resolved)): + if self.ProcessConditional(line_resolved): # was a conditional # Other parser returns line_resolved, []. Need to figure out which is right return ("", []) @@ -205,11 +208,11 @@ def __ParseDefineLine(self, Line: str) -> tuple: # not conditional keep processing # check if conditional is active - if (not self.InActiveCode()): + if not self.InActiveCode(): return ("", []) # check for include file and import lines from file - if (line_resolved.strip().lower().startswith("!include")): + if line_resolved.strip().lower().startswith("!include"): # include line. tokens = line_resolved.split() include_file = tokens[1] @@ -225,7 +228,7 @@ def __ParseDefineLine(self, Line: str) -> tuple: # check for new section (IsNew, Section) = self.ParseNewSection(line_resolved) - if (IsNew): + if IsNew: self.CurrentSection = Section.upper() self.Logger.debug("New Section: %s" % self.CurrentSection) self.Logger.debug("FullSection: %s" % self.CurrentFullSection) @@ -236,7 +239,7 @@ def __ParseDefineLine(self, Line: str) -> tuple: if line_resolved.count("=") >= 1: tokens = line_resolved.split("=", 1) leftside = tokens[0].split() - if (len(leftside) == 2): + if len(leftside) == 2: left = leftside[1] else: left = leftside[0] @@ -254,11 +257,11 @@ def __ParseDefineLine(self, Line: str) -> tuple: def ParseInfPathLib(self, line: str) -> str: """Parses a line with an INF path Lib.""" - if (line.count("|") > 0): + if line.count("|") > 0: line_parts = [] c = line.split("|")[0].strip() i = line.split("|")[1].strip() - if (c in self.LibraryClassToInstanceDict): + if c in self.LibraryClassToInstanceDict: line_parts = self.LibraryClassToInstanceDict.get(c) sp = self.FindPath(i) line_parts.append(sp) @@ -271,19 +274,19 @@ def ParseInfPathMod(self, line: str) -> str: """Parses a line with an INF path.""" return line.strip().split()[0].rstrip("{") - def __ProcessMore(self, lines: list, file_name: Optional[str]=None) -> None: + def __ProcessMore(self, lines: list, file_name: Optional[str] = None) -> None: """Runs after ProcessDefines and does a full parsing of the DSC. Everything is resolved to a final state """ - if (len(lines) == 0): + if len(lines) == 0: return for index in range(len(lines)): # we try here so that we can catch exceptions from individual lines try: raw_line = lines[index] (line, add, new_file) = self.__ParseLine(raw_line, file_name=file_name, lineno=index + 1) - if (len(line) > 0): + if len(line) > 0: self.Lines.append(line) self.__ProcessMore(add, file_name=new_file) except Exception as e: @@ -303,7 +306,7 @@ def __ProcessDefines(self, lines: list) -> None: Ideally this should be run until we reach stable state but this parser is not accurate and is more of an approximation of what the real parser does. """ - if (len(lines) == 0): + if len(lines) == 0: return for raw_line in lines: # we want to catch exceptions here since we are doing includes as we potentially might blow up @@ -440,7 +443,7 @@ def _build_library_override_dictionary(self, lines: List[str]) -> None: if self.OVERRIDE_REGEX.match(l_line): if l_line == f"<{self.SECTION_LIBRARY}>": section = self.SECTION_LIBRARY - else: # Add more sections here if needed + else: # Add more sections here if needed section = "" continue @@ -458,7 +461,7 @@ def _build_library_override_dictionary(self, lines: List[str]) -> None: library_override_dictionary[lib] = instance return library_override_dictionary - def SetNoFailMode(self, enabled: bool=True) -> None: + def SetNoFailMode(self, enabled: bool = True) -> None: """The parser won't throw exceptions when this is turned on. WARNING: This can result in some weird behavior @@ -522,12 +525,9 @@ def GetAllDscPaths(self) -> set: def RegisterPcds(self, line: str) -> None: """Reads the line and registers any PCDs found.""" - if ("tokenspaceguid" in line.lower() and - line.count('|') > 0 and - line.count('.') > 0): - + if "tokenspaceguid" in line.lower() and line.count("|") > 0 and line.count(".") > 0: # should be a pcd statement - p = line.partition('|') + p = line.partition("|") self.Pcds.append(p[0].strip()) self.PcdValueDict[p[0].strip()] = p[2].strip() self.Logger.debug("Found a Pcd: %s" % p[0].strip()) diff --git a/edk2toollib/uefi/edk2/parsers/fdf_parser.py b/edk2toollib/uefi/edk2/parsers/fdf_parser.py index 7b1d378b..c78ea072 100644 --- a/edk2toollib/uefi/edk2/parsers/fdf_parser.py +++ b/edk2toollib/uefi/edk2/parsers/fdf_parser.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Code to help parse EDK2 Fdf files.""" + import os from edk2toollib.uefi.edk2.parsers.base_parser import HashFileParser @@ -25,9 +26,10 @@ class FdfParser(HashFileParser): Note: Dict Key Value pairs come from lines that contain a single =. """ - def __init__(self) -> 'HashFileParser': + + def __init__(self) -> "HashFileParser": """Inits an empty FDF parser.""" - HashFileParser.__init__(self, 'ModuleFdfParser') + HashFileParser.__init__(self, "ModuleFdfParser") self.Lines = [] self.Parsed = False self.Dict = {} # defines dictionary @@ -49,7 +51,7 @@ def GetNextLine(self) -> str: self.CurrentLine += 1 sline = self.StripComment(line) - if (sline is None or len(sline) < 1): + if sline is None or len(sline) < 1: return self.GetNextLine() sline = self.ReplaceVariables(sline) @@ -66,7 +68,7 @@ def GetNextLine(self) -> str: def InsertLinesFromFile(self, file_path: str) -> None: """Adds additional lines to the Lines Attribute from the provided file.""" - with open(file_path, 'r') as lines_file: + with open(file_path, "r") as lines_file: self.Lines += reversed(lines_file.readlines()) # Back off the line count to ignore the include line itself. self.CurrentLine -= 1 @@ -74,7 +76,7 @@ def InsertLinesFromFile(self, file_path: str) -> None: def ParseFile(self, filepath: str) -> None: """Parses the provided FDF file.""" self.Logger.debug("Parsing file: %s" % filepath) - if (not os.path.isabs(filepath)): + if not os.path.isabs(filepath): fp = self.FindPath(filepath) else: fp = filepath @@ -100,7 +102,7 @@ def ParseFile(self, filepath: str) -> None: if sline is None: break - if sline.lower().startswith('!include'): + if sline.lower().startswith("!include"): tokens = sline.split() include_file = tokens[1] sp = self.FindPath(include_file) @@ -114,7 +116,8 @@ def ParseFile(self, filepath: str) -> None: # this basically gets what's after the . or if it doesn't have a period # the whole thing for every comma separated item in sline self.CurrentSection = [ - x.split(".", 1)[1] if "." in x else x for x in sline.strip("[] ").strip().split(",")] + x.split(".", 1)[1] if "." in x else x for x in sline.strip("[] ").strip().split(",") + ] InDefinesSection = False InFdSection = False InFvSection = False @@ -126,14 +129,14 @@ def ParseFile(self, filepath: str) -> None: if InDefinesSection: if sline.count("=") == 1: - tokens = sline.replace("DEFINE", "").split('=', 1) + tokens = sline.replace("DEFINE", "").split("=", 1) self.Dict[tokens[0].strip()] = tokens[1].strip() self.Logger.info("Key,values found: %s = %s" % (tokens[0].strip(), tokens[1].strip())) continue # defining a local variable that is removed when entering a new section elif sline.strip().startswith("DEFINE"): - tokens = sline.strip().replace("DEFINE", "").split('=', 1) + tokens = sline.strip().replace("DEFINE", "").split("=", 1) self.LocalVars[tokens[0].strip()] = tokens[1].strip() self.Logger.info(f"Key,values found for local vars: {tokens[0].strip()}, {tokens[1].strip()}") continue @@ -203,22 +206,22 @@ def ParseFile(self, filepath: str) -> None: continue # check for different sections - if sline.strip().lower().startswith('[defines'): + if sline.strip().lower().startswith("[defines"): InDefinesSection = True - elif sline.strip().lower().startswith('[fd.'): + elif sline.strip().lower().startswith("[fd."): InFdSection = True - elif sline.strip().lower().startswith('[fv.'): + elif sline.strip().lower().startswith("[fv."): InFvSection = True - elif sline.strip().lower().startswith('[capsule.'): + elif sline.strip().lower().startswith("[capsule."): InCapsuleSection = True - elif sline.strip().lower().startswith('[fmpPayload.'): + elif sline.strip().lower().startswith("[fmpPayload."): InFmpPayloadSection = True - elif sline.strip().lower().startswith('[rule.'): + elif sline.strip().lower().startswith("[rule."): InRuleSection = True self.Parsed = True diff --git a/edk2toollib/uefi/edk2/parsers/guid_parser.py b/edk2toollib/uefi/edk2/parsers/guid_parser.py index 031417a3..6e05729d 100644 --- a/edk2toollib/uefi/edk2/parsers/guid_parser.py +++ b/edk2toollib/uefi/edk2/parsers/guid_parser.py @@ -12,11 +12,12 @@ Some functionality copied from Tianocore/edk2 basetools. """ + import re import uuid -class GuidParser(): +class GuidParser: """Provide support functions for converting between different guid formats. Also support str uuid and uuid to string. @@ -25,22 +26,25 @@ class GuidParser(): C-Format: {0xD3B36F2C, 0xD551, 0x11D4, {0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}} Reg-Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx """ + _HexChar = r"[0-9a-fA-F]" # Regular expression for GUID c structure format - _GuidCFormatPattern = r"{{\s*0[xX]{Hex}{{1,8}}\s*,\s*0[xX]{Hex}{{1,4}}\s*,\s*0[xX]{Hex}{{1,4}}" \ - r"\s*,\s*{{\s*0[xX]{Hex}{{1,2}}\s*,\s*0[xX]{Hex}{{1,2}}" \ - r"\s*,\s*0[xX]{Hex}{{1,2}}\s*,\s*0[xX]{Hex}{{1,2}}" \ - r"\s*,\s*0[xX]{Hex}{{1,2}}\s*,\s*0[xX]{Hex}{{1,2}}" \ - r"\s*,\s*0[xX]{Hex}{{1,2}}\s*,\s*0[xX]{Hex}{{1,2}}\s*}}\s*}}".format(Hex=_HexChar) + _GuidCFormatPattern = ( + r"{{\s*0[xX]{Hex}{{1,8}}\s*,\s*0[xX]{Hex}{{1,4}}\s*,\s*0[xX]{Hex}{{1,4}}" + r"\s*,\s*{{\s*0[xX]{Hex}{{1,2}}\s*,\s*0[xX]{Hex}{{1,2}}" + r"\s*,\s*0[xX]{Hex}{{1,2}}\s*,\s*0[xX]{Hex}{{1,2}}" + r"\s*,\s*0[xX]{Hex}{{1,2}}\s*,\s*0[xX]{Hex}{{1,2}}" + r"\s*,\s*0[xX]{Hex}{{1,2}}\s*,\s*0[xX]{Hex}{{1,2}}\s*}}\s*}}".format(Hex=_HexChar) + ) GuidCFormatRegEx = re.compile(r"{}".format(_GuidCFormatPattern)) _GuidPattern = r"{Hex}{{8}}-{Hex}{{4}}-{Hex}{{4}}-{Hex}{{4}}-{Hex}{{12}}".format(Hex=_HexChar) # Regular expressions for GUID matching - GuidRegFormatRegEx = re.compile(r'{}'.format(_GuidPattern)) + GuidRegFormatRegEx = re.compile(r"{}".format(_GuidPattern)) @classmethod - def is_guid_in_c_format(cls: 'GuidParser', guidstring: str) -> bool: + def is_guid_in_c_format(cls: "GuidParser", guidstring: str) -> bool: """Determine if guidstring is in c format. Args: @@ -54,7 +58,7 @@ def is_guid_in_c_format(cls: 'GuidParser', guidstring: str) -> bool: return cls.GuidCFormatRegEx.match(guidstring) @classmethod - def is_guid_in_reg_format(cls: 'GuidParser', guidstring: str) -> bool: + def is_guid_in_reg_format(cls: "GuidParser", guidstring: str) -> bool: """Determine if guidstring is in registry format. Args: @@ -63,11 +67,11 @@ def is_guid_in_reg_format(cls: 'GuidParser', guidstring: str) -> bool: Returns: (bool): True if in Registry format. Otherwise False """ - guidstring = guidstring.strip().strip('} {') + guidstring = guidstring.strip().strip("} {") return cls.GuidRegFormatRegEx.match(guidstring) @classmethod - def reg_guid_from_c_format(cls: 'GuidParser', guidstring: str) -> str: + def reg_guid_from_c_format(cls: "GuidParser", guidstring: str) -> str: """Convert a c formatted guidstring to a registry formatted guidstring. Args: @@ -79,12 +83,12 @@ def reg_guid_from_c_format(cls: 'GuidParser', guidstring: str) -> str: """ guidstring = guidstring.strip() if not cls.is_guid_in_c_format(guidstring): - return '' + return "" guidValueString = guidstring.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "") guidValueList = guidValueString.split(",") if len(guidValueList) != 11: - return '' + return "" try: return "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % ( int(guidValueList[0], 16), @@ -97,13 +101,13 @@ def reg_guid_from_c_format(cls: 'GuidParser', guidstring: str) -> str: int(guidValueList[7], 16), int(guidValueList[8], 16), int(guidValueList[9], 16), - int(guidValueList[10], 16) + int(guidValueList[10], 16), ) except Exception: - return '' + return "" @classmethod - def c_guid_from_reg_format(cls: 'GuidParser', guidstring: str) -> str: + def c_guid_from_reg_format(cls: "GuidParser", guidstring: str) -> str: """Convert registry format guidstring to c format guidstring. Args: @@ -113,33 +117,33 @@ def c_guid_from_reg_format(cls: 'GuidParser', guidstring: str) -> str: (Success): guidstring in c format (Failure): empty string '' """ - guidstring = guidstring.strip().strip('} {') - if (not cls.is_guid_in_reg_format(guidstring)): - return '' + guidstring = guidstring.strip().strip("} {") + if not cls.is_guid_in_reg_format(guidstring): + return "" - GuidList = guidstring.split('-') - Result = '{' + GuidList = guidstring.split("-") + Result = "{" for Index in range(0, 3, 1): - Result = Result + '0x' + GuidList[Index] + ', ' - Result = Result + '{0x' + GuidList[3][0:2] + ', 0x' + GuidList[3][2:4] + Result = Result + "0x" + GuidList[Index] + ", " + Result = Result + "{0x" + GuidList[3][0:2] + ", 0x" + GuidList[3][2:4] for Index in range(0, 12, 2): - Result = Result + ', 0x' + GuidList[4][Index:Index + 2] - Result += '}}' + Result = Result + ", 0x" + GuidList[4][Index : Index + 2] + Result += "}}" return Result @classmethod - def uuid_from_guidstring(cls: 'GuidParser', guidstring: str) -> uuid.UUID: + def uuid_from_guidstring(cls: "GuidParser", guidstring: str) -> uuid.UUID: """Create a uuid object from the supplied guidstring.""" - if (cls.is_guid_in_c_format(guidstring)): + if cls.is_guid_in_c_format(guidstring): return uuid.UUID(cls.reg_guid_from_c_format(guidstring)) - elif (cls.is_guid_in_reg_format(guidstring)): - guidstring = guidstring.strip().strip('} {') + elif cls.is_guid_in_reg_format(guidstring): + guidstring = guidstring.strip().strip("} {") return uuid.UUID(guidstring) else: return None @classmethod - def c_guid_str_from_uuid(cls: 'GuidParser', guid: uuid.UUID) -> str: + def c_guid_str_from_uuid(cls: "GuidParser", guid: uuid.UUID) -> str: """Get a C string formatted guidstring from a uuid object. Args: @@ -153,7 +157,7 @@ def c_guid_str_from_uuid(cls: 'GuidParser', guid: uuid.UUID) -> str: return cls.c_guid_from_reg_format(reg) @classmethod - def reg_guid_str_from_uuid(cls: 'GuidParser', guid: uuid.UUID) -> str: + def reg_guid_str_from_uuid(cls: "GuidParser", guid: uuid.UUID) -> str: """Get a registry string formatted guidstring from a uuid object. Args: diff --git a/edk2toollib/uefi/edk2/parsers/inf_parser.py b/edk2toollib/uefi/edk2/parsers/inf_parser.py index 021e0ef6..6adf8e72 100644 --- a/edk2toollib/uefi/edk2/parsers/inf_parser.py +++ b/edk2toollib/uefi/edk2/parsers/inf_parser.py @@ -6,14 +6,27 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Code to help parse EDK2 INF files.""" + import os import re from edk2toollib.uefi.edk2.parsers.base_parser import HashFileParser -AllPhases = ["SEC", "PEIM", "PEI_CORE", "DXE_DRIVER", "DXE_CORE", "DXE_RUNTIME_DRIVER", "UEFI_DRIVER", - "SMM_CORE", "DXE_SMM_DRIVER", "UEFI_APPLICATION", "MM_STANDALONE", "MM_CORE_STANDALONE", - "HOST_APPLICATION",] +AllPhases = [ + "SEC", + "PEIM", + "PEI_CORE", + "DXE_DRIVER", + "DXE_CORE", + "DXE_RUNTIME_DRIVER", + "UEFI_DRIVER", + "SMM_CORE", + "DXE_SMM_DRIVER", + "UEFI_APPLICATION", + "MM_STANDALONE", + "MM_CORE_STANDALONE", + "HOST_APPLICATION", +] class InfParser(HashFileParser): @@ -37,13 +50,14 @@ class InfParser(HashFileParser): NOTE: Key / Value pairs determined by lines that contain a single = """ + SECTION_REGEX = re.compile(r"\[(.*)\]") - SECTION_LIBRARY = re.compile(r'libraryclasses(?:\.([^,.\]]+))?[,.\]]', re.IGNORECASE) - SECTION_SOURCE = re.compile(r'sources(?:\.([^,.\]]+))?[,.\]]', re.IGNORECASE) + SECTION_LIBRARY = re.compile(r"libraryclasses(?:\.([^,.\]]+))?[,.\]]", re.IGNORECASE) + SECTION_SOURCE = re.compile(r"sources(?:\.([^,.\]]+))?[,.\]]", re.IGNORECASE) - def __init__(self) -> 'InfParser': + def __init__(self) -> "InfParser": """Inits an empty parser.""" - HashFileParser.__init__(self, 'ModuleInfParser') + HashFileParser.__init__(self, "ModuleInfParser") self.Lines = [] self.Parsed = False self.Dict = {} @@ -80,7 +94,7 @@ def get_sources(self, arch_list: list[str]) -> list[str]: def ParseFile(self, filepath: str) -> None: """Parses the INF file provided.""" self.Logger.debug("Parsing file: %s" % filepath) - if (not os.path.isabs(filepath)): + if not os.path.isabs(filepath): fp = self.FindPath(filepath) else: fp = filepath @@ -101,33 +115,33 @@ def ParseFile(self, filepath: str) -> None: for line in self.Lines: sline = self.StripComment(line) - if (sline is None or len(sline) < 1): + if sline is None or len(sline) < 1: continue sline = self.ReplaceVariables(sline) if sline.strip().startswith("DEFINE"): - tokens = sline.strip().replace("DEFINE", "").split('=', 1) + tokens = sline.strip().replace("DEFINE", "").split("=", 1) self.LocalVars[tokens[0].strip()] = tokens[1].strip() self.Logger.info(f"Key,values found for local vars: {tokens[0].strip()}, {tokens[1].strip()}") continue elif InDefinesSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InDefinesSection = False else: if sline.count("=") == 1: - tokens = sline.split('=', 1) + tokens = sline.split("=", 1) self.Dict[tokens[0].strip()] = tokens[1].strip() # # Parse Library class and phases in special manor # - if (tokens[0].strip().lower() == "library_class"): + if tokens[0].strip().lower() == "library_class": self.LibraryClass = tokens[1].partition("|")[0].strip() self.Logger.debug("Library class found") - if (len(tokens[1].partition("|")[2].strip()) < 1): + if len(tokens[1].partition("|")[2].strip()) < 1: self.SupportedPhases = AllPhases - elif (tokens[1].partition("|")[2].strip().lower() == "base"): + elif tokens[1].partition("|")[2].strip().lower() == "base": self.SupportedPhases = AllPhases else: self.SupportedPhases = tokens[1].partition("|")[2].strip().split() @@ -137,90 +151,92 @@ def ParseFile(self, filepath: str) -> None: continue elif InPackagesSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InPackagesSection = False else: self.PackagesUsed.append(sline.partition("|")[0].strip()) continue elif InLibraryClassSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InLibraryClassSection = False else: self.LibrariesUsed.append(sline.partition("|")[0].strip()) continue elif InProtocolsSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InProtocolsSection = False else: self.ProtocolsUsed.append(sline.partition("|")[0].strip()) continue elif InGuidsSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InGuidsSection = False else: self.GuidsUsed.append(sline.partition("|")[0].strip()) continue elif InPcdSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InPcdSection = False else: self.PcdsUsed.append(sline.partition("|")[0].strip()) continue elif InPpiSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InPpiSection = False else: self.PpisUsed.append(sline.partition("|")[0].strip()) continue elif InSourcesSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InSourcesSection = False else: self.Sources.append(sline.partition("|")[0].strip()) continue elif InBinariesSection: - if sline.strip()[0] == '[': + if sline.strip()[0] == "[": InBinariesSection = False else: self.Binaries.append(sline.partition("|")[0].strip()) continue # check for different sections - if sline.strip().lower().startswith('[defines'): + if sline.strip().lower().startswith("[defines"): InDefinesSection = True - elif sline.strip().lower().startswith('[packages'): + elif sline.strip().lower().startswith("[packages"): InPackagesSection = True - elif sline.strip().lower().startswith('[libraryclasses'): + elif sline.strip().lower().startswith("[libraryclasses"): InLibraryClassSection = True - elif sline.strip().lower().startswith('[protocols'): + elif sline.strip().lower().startswith("[protocols"): InProtocolsSection = True - elif sline.strip().lower().startswith('[ppis'): + elif sline.strip().lower().startswith("[ppis"): InPpiSection = True - elif sline.strip().lower().startswith('[guids'): + elif sline.strip().lower().startswith("[guids"): InGuidsSection = True - elif sline.strip().lower().startswith('[pcd') or \ - sline.strip().lower().startswith('[patchpcd') or \ - sline.strip().lower().startswith('[fixedpcd') or \ - sline.strip().lower().startswith('[featurepcd'): + elif ( + sline.strip().lower().startswith("[pcd") + or sline.strip().lower().startswith("[patchpcd") + or sline.strip().lower().startswith("[fixedpcd") + or sline.strip().lower().startswith("[featurepcd") + ): InPcdSection = True - elif sline.strip().lower().startswith('[sources'): + elif sline.strip().lower().startswith("[sources"): InSourcesSection = True - elif sline.strip().lower().startswith('[binaries'): + elif sline.strip().lower().startswith("[binaries"): InBinariesSection = True # Re-parse for scoped information @@ -239,7 +255,7 @@ def ParseFile(self, filepath: str) -> None: continue if line.strip().startswith("DEFINE"): - tokens = line.strip().replace("DEFINE", "").split('=', 1) + tokens = line.strip().replace("DEFINE", "").split("=", 1) self.LocalVars[tokens[0].strip()] = tokens[1].strip() self.Logger.info(f"Key,values found for local vars: {tokens[0].strip()}, {tokens[1].strip()}") continue @@ -266,7 +282,7 @@ def ParseFile(self, filepath: str) -> None: # Handle lines when we are in a library section if current_section == "LibraryClasses": for arch in arch_list: - arch = 'common' if arch == '' else arch.lower() + arch = "common" if arch == "" else arch.lower() if arch in self.ScopedLibraryDict: self.ScopedLibraryDict[arch].append(line.split()[0].strip()) else: @@ -275,8 +291,8 @@ def ParseFile(self, filepath: str) -> None: # Handle lines when we are in a source section if current_section == "Sources": for arch in arch_list: - arch = 'common' if arch == '' else arch.lower() - src = line.split()[0].strip().rstrip('|') + arch = "common" if arch == "" else arch.lower() + src = line.split()[0].strip().rstrip("|") if arch in self.ScopedSourceDict: self.ScopedSourceDict[arch].append(src) else: diff --git a/edk2toollib/uefi/edk2/parsers/override_parser.py b/edk2toollib/uefi/edk2/parsers/override_parser.py index 6645da36..3202b719 100644 --- a/edk2toollib/uefi/edk2/parsers/override_parser.py +++ b/edk2toollib/uefi/edk2/parsers/override_parser.py @@ -8,24 +8,25 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Contains classes to help with parsing INF files that may contain OVERRIDE information.""" + import datetime import os from typing import Optional -FORMAT_VERSION_1 = (1, 4) # Version 1: #OVERRIDE : VERSION | PATH_TO_MODULE | HASH | YYYY-MM-DDThh-mm-ss +FORMAT_VERSION_1 = (1, 4) # Version 1: #OVERRIDE : VERSION | PATH_TO_MODULE | HASH | YYYY-MM-DDThh-mm-ss class OpParseError(Exception): """Class representing OpParseError types.""" - PE_VER = 'VERSION' - PE_PATH = 'PATH' - PE_HASH = 'HASH' - PE_DATE = 'DATE' - def __init__(self, my_type: str) -> 'OpParseError': + PE_VER = "VERSION" + PE_PATH = "PATH" + PE_HASH = "HASH" + PE_DATE = "DATE" + + def __init__(self, my_type: str) -> "OpParseError": """Verifies type is a valid OpParseError type.""" - if my_type not in (OpParseError.PE_VER, OpParseError.PE_PATH, - OpParseError.PE_HASH, OpParseError.PE_DATE): + if my_type not in (OpParseError.PE_VER, OpParseError.PE_PATH, OpParseError.PE_HASH, OpParseError.PE_DATE): raise ValueError("Unknown type '%s'" % my_type) self.type = my_type @@ -54,7 +55,8 @@ class OverrideParser(object): parsers. The pros and cons of this should also be weighed during any parser refactor. """ - def __init__(self, file_path: Optional[str]=None, inf_contents: Optional[str]=None) -> 'OverrideParser': + + def __init__(self, file_path: Optional[str] = None, inf_contents: Optional[str] = None) -> "OverrideParser": """Inits and parses either a file or already parsed contents. Args: @@ -76,12 +78,12 @@ def __init__(self, file_path: Optional[str]=None, inf_contents: Optional[str]=No if not os.path.isfile(file_path): raise ValueError("File path '%s' does not exist." % file_path) - self.file_path = os.path.abspath(file_path) if file_path is not None else 'String Buffer' + self.file_path = os.path.abspath(file_path) if file_path is not None else "String Buffer" # Set up the contents for parsing. parse_contents = inf_contents if file_path is not None: - with open(file_path, 'r') as file: + with open(file_path, "r") as file: parse_contents = file.read() if not parse_contents: raise ValueError("Failed to read contents of file '%s'." % self.file_path) @@ -95,10 +97,12 @@ def __init__(self, file_path: Optional[str]=None, inf_contents: Optional[str]=No self.overrides = [] for override_line in self.override_lines: try: - self.overrides.append(self.parse_override_line(override_line['line'])) + self.overrides.append(self.parse_override_line(override_line["line"])) except OpParseError as pe: - raise ValueError("Parse error '%s' occurred while processing line %d of '%s'." % - (pe, override_line['lineno'], override_line['line'])) + raise ValueError( + "Parse error '%s' occurred while processing line %d of '%s'." + % (pe, override_line["lineno"], override_line["line"]) + ) @staticmethod def get_override_lines(parse_contents: str) -> list: @@ -107,12 +111,12 @@ def get_override_lines(parse_contents: str) -> list: Returns: (list[str]): lines starting with #OVERRIDE """ - parse_lines = parse_contents.split('\n') + parse_lines = parse_contents.split("\n") result = [] for i in range(len(parse_lines)): if parse_lines[i].strip().upper().startswith("#OVERRIDE"): - result.append({'lineno': i + 1, 'line': parse_lines[i].strip()}) + result.append({"lineno": i + 1, "line": parse_lines[i].strip()}) return result @@ -139,24 +143,24 @@ def parse_override_line(line_contents: str) -> dict: # Step 1: Check version and number of blocks in this entry try: - result['version'] = int(line_parts[0]) + result["version"] = int(line_parts[0]) except ValueError: raise OpParseError(OpParseError.PE_VER) # Verify this is a known version and has valid number of entries - if not ((result['version'] == FORMAT_VERSION_1[0]) and (len(line_parts) == FORMAT_VERSION_1[1])): + if not ((result["version"] == FORMAT_VERSION_1[0]) and (len(line_parts) == FORMAT_VERSION_1[1])): raise OpParseError(OpParseError.PE_VER) # Step 2: Process the path to overridden module # Normalize the path to support different slashes. - result['original_path'] = os.path.normpath(line_parts[1]) + result["original_path"] = os.path.normpath(line_parts[1]) # Step 3: Grep hash entry - result['current_hash'] = line_parts[2] + result["current_hash"] = line_parts[2] # Step 4: Parse the time of hash generation try: - result['datetime'] = datetime.datetime.strptime(line_parts[3], "%Y-%m-%dT%H-%M-%S") + result["datetime"] = datetime.datetime.strptime(line_parts[3], "%Y-%m-%dT%H-%M-%S") except ValueError: raise OpParseError(OpParseError.PE_DATE) diff --git a/edk2toollib/uefi/edk2/parsers/targettxt_parser.py b/edk2toollib/uefi/edk2/parsers/targettxt_parser.py index 454c695a..607496d9 100644 --- a/edk2toollib/uefi/edk2/parsers/targettxt_parser.py +++ b/edk2toollib/uefi/edk2/parsers/targettxt_parser.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Code to help parse Edk2 Conf/Target.txt file.""" + import os from edk2toollib.uefi.edk2.parsers.base_parser import HashFileParser @@ -20,9 +21,10 @@ class TargetTxtParser(HashFileParser): Dict (dict): Key / Value pair of all lines that contain a `=` in them (key=value) Path (str): path to Target.txt file """ - def __init__(self) -> 'TargetTxtParser': + + def __init__(self) -> "TargetTxtParser": """Inits an empty parser.""" - HashFileParser.__init__(self, 'TargetTxtParser') + HashFileParser.__init__(self, "TargetTxtParser") self.Lines = [] self.Parsed = False self.Dict = {} @@ -31,7 +33,7 @@ def __init__(self) -> 'TargetTxtParser': def ParseFile(self, filepath: str) -> None: """Parses the file provided.""" self.Logger.debug("Parsing file: %s" % filepath) - if (not os.path.isabs(filepath)): + if not os.path.isabs(filepath): fp = self.FindPath(filepath) else: fp = filepath @@ -43,11 +45,11 @@ def ParseFile(self, filepath: str) -> None: for line in self.Lines: sline = self.StripComment(line) - if (sline is None or len(sline) < 1): + if sline is None or len(sline) < 1: continue if sline.count("=") == 1: - tokens = sline.split('=', 1) + tokens = sline.split("=", 1) self.Dict[tokens[0].strip()] = tokens[1].strip() self.Logger.debug("Key,values found: %s = %s" % (tokens[0].strip(), tokens[1].strip())) continue diff --git a/edk2toollib/uefi/edk2/path_utilities.py b/edk2toollib/uefi/edk2/path_utilities.py index 55a48ce2..dfba2a31 100644 --- a/edk2toollib/uefi/edk2/path_utilities.py +++ b/edk2toollib/uefi/edk2/path_utilities.py @@ -11,6 +11,7 @@ the OS specific path with the exception of of any function that returns an Edk2 style path, which will always return Posix form. """ + import errno import logging import os @@ -36,8 +37,9 @@ class Edk2Path(object): passed to any consumers. """ - def __init__(self, ws: os.PathLike, package_path_list: Iterable[os.PathLike], - error_on_invalid_pp: bool = True) -> 'Edk2Path': + def __init__( + self, ws: os.PathLike, package_path_list: Iterable[os.PathLike], error_on_invalid_pp: bool = True + ) -> "Edk2Path": """Constructor. Args: @@ -61,10 +63,7 @@ def __init__(self, ws: os.PathLike, package_path_list: Iterable[os.PathLike], workspace_candidate_path = Path.cwd() / ws if not workspace_candidate_path.is_dir(): - raise NotADirectoryError( - errno.ENOENT, - os.strerror(errno.ENOENT), - workspace_candidate_path.resolve()) + raise NotADirectoryError(errno.ENOENT, os.strerror(errno.ENOENT), workspace_candidate_path.resolve()) self._workspace_path = workspace_candidate_path @@ -83,9 +82,10 @@ def __init__(self, ws: os.PathLike, package_path_list: Iterable[os.PathLike], invalid_pp = [] for a in candidate_package_path_list[:]: if not a.is_dir(): - self.logger.log(logging.ERROR if error_on_invalid_pp else - logging.WARNING, - f"Invalid package path entry {a.resolve()}") + self.logger.log( + logging.ERROR if error_on_invalid_pp else logging.WARNING, + f"Invalid package path entry {a.resolve()}", + ) candidate_package_path_list.remove(a) invalid_pp.append(str(a.resolve())) @@ -106,39 +106,41 @@ def __init__(self, ws: os.PathLike, package_path_list: Iterable[os.PathLike], # 3. Raise an Exception if two packages are found to be nested. # if "PYTOOL_TEMPORARILY_IGNORE_NESTED_EDK_PACKAGES" in os.environ: - warning = "PYTOOL_TEMPORARILY_IGNORE_NESTED_EDK_PACKAGES is no longer used by edk2-pytool-library, but is "\ - "detected in your environment. Please remove this environment variable." + warning = ( + "PYTOOL_TEMPORARILY_IGNORE_NESTED_EDK_PACKAGES is no longer used by edk2-pytool-library, but is " + "detected in your environment. Please remove this environment variable." + ) self.logger.log(logging.WARNING, warning) if "PYTOOL_IGNORE_KNOWN_BAD_NESTED_PACKAGES" == os.environ: - warning = "PYTOOL_IGNORE_KNOWN_BAD_NESTED_PACKAGES is no longer used by edk2-pytool-library, but is " \ - "detected in your environment. Please remove this environment variable." + warning = ( + "PYTOOL_IGNORE_KNOWN_BAD_NESTED_PACKAGES is no longer used by edk2-pytool-library, but is " + "detected in your environment. Please remove this environment variable." + ) self.logger.log(logging.WARNING, warning) package_path_packages = {} for package_path in self._package_path_list: - package_path_packages[package_path] = \ - [p.parent for p in package_path.glob('**/*.dec')] + package_path_packages[package_path] = [p.parent for p in package_path.glob("**/*.dec")] for package_path, packages in package_path_packages.items(): for i, package in enumerate(packages): for j in range(i + 1, len(packages)): comp_package = packages[j] - if (package.is_relative_to(comp_package) - or comp_package.is_relative_to(package)): + if package.is_relative_to(comp_package) or comp_package.is_relative_to(package): self.logger.log( logging.DEBUG, f"[{str(package)}] and [{str(comp_package)}] are nested. Nested packages are not allowed " "and may result in incorrect conversions from absolute path to edk2 package path relative " - "paths." + "paths.", ) @property - def WorkspacePath(self: 'Edk2Path') -> str: + def WorkspacePath(self: "Edk2Path") -> str: """Workspace Path as a string.""" return str(self._workspace_path) @property - def PackagePathList(self: 'Edk2Path') -> list[str]: + def PackagePathList(self: "Edk2Path") -> list[str]: """List of package paths as strings.""" return [str(p) for p in self._package_path_list] @@ -175,7 +177,6 @@ def GetEdk2RelativePathFromAbsolutePath(self, *abspath: Tuple[str, ...]) -> str: # path are in the same directory. See the following path_utilities_test for a detailed explanation of the # scenario: test_get_relative_path_when_folder_is_next_to_package for packagepath in sorted(self._package_path_list, reverse=True): - # If a match is found, use the original string to avoid change in case if abspath.is_relative_to(packagepath): self.logger.debug("Successfully converted AbsPath to Edk2Relative Path using PackagePath") @@ -191,16 +192,16 @@ def GetEdk2RelativePathFromAbsolutePath(self, *abspath: Tuple[str, ...]) -> str: if found: relpath = relpath.as_posix() - self.logger.debug(f'[{abspath}] -> [{relpath}]') + self.logger.debug(f"[{abspath}] -> [{relpath}]") return relpath # Absolute path was not in reference to a package path or the workspace root. self.logger.error("Failed to convert AbsPath to Edk2Relative Path") - self.logger.error(f'AbsolutePath: {abspath}') + self.logger.error(f"AbsolutePath: {abspath}") return None def GetAbsolutePathOnThisSystemFromEdk2RelativePath( - self, *relpath: Tuple[str, ...], log_errors: Optional[bool]=True + self, *relpath: Tuple[str, ...], log_errors: Optional[bool] = True ) -> str: """Given a relative path return an absolute path to the file in this workspace. @@ -278,7 +279,7 @@ def GetContainingPackage(self, InputPath: str) -> str: while path_root != dirpath: if dirpath.exists(): for f in dirpath.iterdir(): - if f.suffix.lower() =='.dec': + if f.suffix.lower() == ".dec": return dirpath.name dirpath = dirpath.parent @@ -337,7 +338,7 @@ def GetContainingModules(self, input_path: str) -> list[str]: return [] modules = [] - if input_path.suffix.lower() == '.inf': + if input_path.suffix.lower() == ".inf": # Return the file path given since it is a module .inf file modules = [str(input_path)] @@ -365,9 +366,9 @@ def GetContainingModules(self, input_path: str) -> list[str]: current_dir = input_path.parent while current_dir not in maximum_root_paths: if current_dir.is_dir(): - current_dir_inf_files = \ - [str(f) for f in current_dir.iterdir() if - f.is_file() and f.suffix.lower() == '.inf'] + current_dir_inf_files = [ + str(f) for f in current_dir.iterdir() if f.is_file() and f.suffix.lower() == ".inf" + ] if current_dir_inf_files: # A .inf file(s) exist in this directory. # diff --git a/edk2toollib/uefi/edk2/variable_format.py b/edk2toollib/uefi/edk2/variable_format.py index 579ea013..1b4ecb70 100644 --- a/edk2toollib/uefi/edk2/variable_format.py +++ b/edk2toollib/uefi/edk2/variable_format.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Module contains helper classes and functions to work with UEFI Variables.""" + import struct import sys import uuid @@ -45,7 +46,8 @@ class VariableStoreHeader(object): UINT32 Reserved1; } VARIABLE_STORE_HEADER; """ - def __init__(self) -> 'VariableStoreHeader': + + def __init__(self) -> "VariableStoreHeader": """Init the empty structure.""" self.StructString = "=16sLBBHL" # spell-checker: disable-line self.StructSize = struct.calcsize(self.StructString) @@ -55,9 +57,9 @@ def __init__(self) -> 'VariableStoreHeader': self.State = None self.Reserved0 = None self.Reserved1 = None - self.Type = 'Var' + self.Type = "Var" - def load_from_file(self, file: str) -> 'VariableStoreHeader': + def load_from_file(self, file: str) -> "VariableStoreHeader": """Load the structure from a file.""" # This function assumes that the file has been seeked # to the correct starting location. @@ -66,11 +68,12 @@ def load_from_file(self, file: str) -> 'VariableStoreHeader': file.seek(orig_seek) # Load this object with the contents of the data. - (signature_bin, self.Size, self.Format, self.State, self.Reserved0, - self.Reserved1) = struct.unpack(self.StructString, struct_bytes) + (signature_bin, self.Size, self.Format, self.State, self.Reserved0, self.Reserved1) = struct.unpack( + self.StructString, struct_bytes + ) # Update the GUID to be a UUID object. - if sys.byteorder == 'big': + if sys.byteorder == "big": self.Signature = uuid.UUID(bytes=signature_bin) else: self.Signature = uuid.UUID(bytes_le=signature_bin) @@ -79,15 +82,16 @@ def load_from_file(self, file: str) -> 'VariableStoreHeader': if self.Signature != EfiVariableGuid and self.Signature != EfiAuthenticatedVariableGuid: raise Exception("VarStore is of unknown type! %s" % self.Signature) if self.Signature == EfiAuthenticatedVariableGuid: - self.Type = 'AuthVar' + self.Type = "AuthVar" return self def serialize(self) -> bytes: """Serialize the structure.""" - signature_bin = self.Signature.bytes if sys.byteorder == 'big' else self.Signature.bytes_le - return struct.pack(self.StructString, signature_bin, self.Size, self.Format, - self.State, self.Reserved0, self.Reserved1) + signature_bin = self.Signature.bytes if sys.byteorder == "big" else self.Signature.bytes_le + return struct.pack( + self.StructString, signature_bin, self.Size, self.Format, self.State, self.Reserved0, self.Reserved1 + ) # @@ -110,13 +114,14 @@ class VariableHeader(object): EFI_GUID VendorGuid; } VARIABLE_HEADER; """ - def __init__(self) -> 'VariableHeader': + + def __init__(self) -> "VariableHeader": """Init the structure.""" self.StructString = "=HBBLLL16s" # spell-checker: disable-line self.StructSize = struct.calcsize(self.StructString) self.StartId = VARIABLE_DATA self.State = VAR_ADDED - self.Attributes = (ump.EFI_VARIABLE_NON_VOLATILE | ump.EFI_VARIABLE_BOOTSERVICE_ACCESS) + self.Attributes = ump.EFI_VARIABLE_NON_VOLATILE | ump.EFI_VARIABLE_BOOTSERVICE_ACCESS self.NameSize = 0 self.DataSize = 0 self.VendorGuid = uuid.uuid4() @@ -125,16 +130,17 @@ def __init__(self) -> 'VariableHeader': def populate_structure_fields(self, in_bytes: bytes) -> None: """Populate the structure field from bytes.""" - (self.StartId, self.State, reserved, self.Attributes, self.NameSize, - self.DataSize, self.VendorGuid) = struct.unpack(self.StructString, in_bytes) + (self.StartId, self.State, reserved, self.Attributes, self.NameSize, self.DataSize, self.VendorGuid) = ( + struct.unpack(self.StructString, in_bytes) + ) - def load_from_bytes(self, in_bytes: bytes) -> 'VariableHeader': + def load_from_bytes(self, in_bytes: bytes) -> "VariableHeader": """Load the structure from a bytes.""" # Load this object with the contents of the data. - self.populate_structure_fields(in_bytes[0:self.StructSize]) + self.populate_structure_fields(in_bytes[0 : self.StructSize]) # Update the GUID to be a UUID object. - if sys.byteorder == 'big': + if sys.byteorder == "big": self.VendorGuid = uuid.UUID(bytes=self.VendorGuid) else: self.VendorGuid = uuid.UUID(bytes_le=self.VendorGuid) @@ -145,14 +151,14 @@ def load_from_bytes(self, in_bytes: bytes) -> 'VariableHeader': # Finally, load the data. data_offset = self.StructSize - self.Name = in_bytes[data_offset:(data_offset + self.NameSize)].decode('utf-16') + self.Name = in_bytes[data_offset : (data_offset + self.NameSize)].decode("utf-16") self.Name = self.Name[:-1] # Strip the terminating char. data_offset += self.NameSize - self.Data = in_bytes[data_offset:(data_offset + self.DataSize)] + self.Data = in_bytes[data_offset : (data_offset + self.DataSize)] return self - def load_from_file(self, file: str) -> 'VariableHeader': + def load_from_file(self, file: str) -> "VariableHeader": """Load the struct from a file.""" # This function assumes that the file has been seeked # to the correct starting location. @@ -163,7 +169,7 @@ def load_from_file(self, file: str) -> 'VariableHeader': self.populate_structure_fields(struct_bytes) # Update the GUID to be a UUID object. - if sys.byteorder == 'big': + if sys.byteorder == "big": self.VendorGuid = uuid.UUID(bytes=self.VendorGuid) else: self.VendorGuid = uuid.UUID(bytes_le=self.VendorGuid) @@ -174,7 +180,7 @@ def load_from_file(self, file: str) -> 'VariableHeader': raise EOFError("No variable data!") # Finally, load the data. - self.Name = file.read(self.NameSize).decode('utf-16')[:-1] # Strip the terminating char. + self.Name = file.read(self.NameSize).decode("utf-16")[:-1] # Strip the terminating char. self.Data = file.read(self.DataSize) file.seek(orig_seek) @@ -200,7 +206,7 @@ def get_packed_name(self) -> bytes: """Get the name attribute.""" # Make sure to replace the terminating char. # name_bytes = b"\x00".join([char for char in (self.Name + b'\x00')]) - name_bytes = self.Name.encode('utf-16') + name_bytes = self.Name.encode("utf-16") # Python encode will leave an "0xFFFE" on the front # to declare the encoding type. UEFI does not use this. @@ -223,11 +229,12 @@ def set_data(self, new_data: bytes) -> None: def pack_struct(self) -> bytes: """Pack the object.""" - vendor_guid = self.VendorGuid.bytes if sys.byteorder == 'big' else self.VendorGuid.bytes_le - return struct.pack(self.StructString, self.StartId, self.State, 0, self.Attributes, - self.NameSize, self.DataSize, vendor_guid) + vendor_guid = self.VendorGuid.bytes if sys.byteorder == "big" else self.VendorGuid.bytes_le + return struct.pack( + self.StructString, self.StartId, self.State, 0, self.Attributes, self.NameSize, self.DataSize, vendor_guid + ) - def serialize(self, with_padding: bool=False) -> bytes: + def serialize(self, with_padding: bool = False) -> bytes: """Serialize the object.""" bytes = self.pack_struct() @@ -237,7 +244,7 @@ def serialize(self, with_padding: bool=False) -> bytes: # Add padding if necessary. if with_padding: - bytes += b"\xFF" * self.get_buffer_padding_size() + bytes += b"\xff" * self.get_buffer_padding_size() return bytes @@ -260,26 +267,48 @@ class AuthenticatedVariableHeader(VariableHeader): EFI_GUID VendorGuid; } AUTHENTICATED_VARIABLE_HEADER; """ - def __init__(self) -> 'AuthenticatedVariableHeader': + + def __init__(self) -> "AuthenticatedVariableHeader": """Initializes the struct.""" super(AuthenticatedVariableHeader, self).__init__() self.StructString = "=HBBLQ16sLLL16s" # spell-checker: disable-line self.StructSize = struct.calcsize(self.StructString) self.MonotonicCount = 0 - self.TimeStamp = b'' + self.TimeStamp = b"" self.PubKeyIndex = 0 def populate_structure_fields(self, in_bytes: bytes) -> None: """Populates the struct.""" - (self.StartId, self.State, reserved, self.Attributes, self.MonotonicCount, self.TimeStamp, self.PubKeyIndex, - self.NameSize, self.DataSize, self.VendorGuid) = struct.unpack(self.StructString, in_bytes) - - def pack_struct(self, with_padding: bool=False) -> bytes: + ( + self.StartId, + self.State, + reserved, + self.Attributes, + self.MonotonicCount, + self.TimeStamp, + self.PubKeyIndex, + self.NameSize, + self.DataSize, + self.VendorGuid, + ) = struct.unpack(self.StructString, in_bytes) + + def pack_struct(self, with_padding: bool = False) -> bytes: """Packs the struct.""" - vendor_guid = self.VendorGuid.bytes if sys.byteorder == 'big' else self.VendorGuid.bytes_le - return struct.pack(self.StructString, self.StartId, self.State, 0, self.Attributes, self.MonotonicCount, - self.TimeStamp, self.PubKeyIndex, self.NameSize, self.DataSize, vendor_guid) - - -if __name__ == '__main__': + vendor_guid = self.VendorGuid.bytes if sys.byteorder == "big" else self.VendorGuid.bytes_le + return struct.pack( + self.StructString, + self.StartId, + self.State, + 0, + self.Attributes, + self.MonotonicCount, + self.TimeStamp, + self.PubKeyIndex, + self.NameSize, + self.DataSize, + vendor_guid, + ) + + +if __name__ == "__main__": pass diff --git a/edk2toollib/uefi/edk2/variable_policy.py b/edk2toollib/uefi/edk2/variable_policy.py index d80f2db5..5843a930 100644 --- a/edk2toollib/uefi/edk2/variable_policy.py +++ b/edk2toollib/uefi/edk2/variable_policy.py @@ -7,6 +7,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Module containing helper classes and functions to work with Variable Policy structures and substructures.""" + import struct import uuid from typing import IO @@ -24,12 +25,13 @@ class VariableLockOnVarStatePolicy(object): // CHAR16 Name[]; // Variable Length Field } VARIABLE_LOCK_ON_VAR_STATE_POLICY; """ + _HdrStructFormat = "<16sBB" _HdrStructSize = struct.calcsize(_HdrStructFormat) - def __init__(self) -> 'VariableLockOnVarStatePolicy': + def __init__(self) -> "VariableLockOnVarStatePolicy": """Initializes the Variable Lock On Var State Policy.""" - self.Namespace = uuid.UUID(bytes=b'\x00' * 16) + self.Namespace = uuid.UUID(bytes=b"\x00" * 16) self.Value = 0 self.Name = None @@ -43,13 +45,12 @@ def decode(self, buffer: IO) -> bytes: Returns: (obj): any remaining buffer """ - (_namespace, self.Value, _) = struct.unpack( - self._HdrStructFormat, buffer[:self._HdrStructSize]) + (_namespace, self.Value, _) = struct.unpack(self._HdrStructFormat, buffer[: self._HdrStructSize]) self.Namespace = uuid.UUID(bytes_le=_namespace) # Scan the rest of the buffer for a \x00\x00 to terminate the string. - buffer = buffer[self._HdrStructSize:] + buffer = buffer[self._HdrStructSize :] if len(buffer) < 4: raise ValueError("Buffer too short!") @@ -62,7 +63,7 @@ def decode(self, buffer: IO) -> bytes: if string_end is None: raise ValueError("String end not detected!") - self.Name = buffer[:string_end].decode('utf-16').strip('\x00') + self.Name = buffer[:string_end].decode("utf-16").strip("\x00") return buffer[string_end:] @@ -86,7 +87,8 @@ class VariablePolicyEntry(object): // CHAR16 Name[] // Variable Length Field } VARIABLE_POLICY_ENTRY; """ - _HdrStructFormat = " 'VariablePolicyEntry': + def __init__(self) -> "VariablePolicyEntry": """Initializes the Variable Policy Entry.""" self.Version = VariablePolicyEntry.ENTRY_REVISION self.Size = VariablePolicyEntry._HdrStructSize self.OffsetToName = self.Size - self.Namespace = uuid.UUID(bytes=b'\x00' * 16) + self.Namespace = uuid.UUID(bytes=b"\x00" * 16) self.MinSize = VariablePolicyEntry.NO_MIN_SIZE self.MaxSize = VariablePolicyEntry.NO_MAX_SIZE self.AttributesMustHave = VariablePolicyEntry.NO_MUST_ATTR @@ -126,23 +128,39 @@ def __str__(self) -> str: """String representation of the object.""" result = "VARIABLE_POLICY_ENTRY(%s, %s)\n" % (self.Namespace, self.Name) - if self.LockPolicyType in (VariablePolicyEntry.TYPE_NO_LOCK, - VariablePolicyEntry.TYPE_LOCK_NOW, - VariablePolicyEntry.TYPE_LOCK_ON_CREATE): + if self.LockPolicyType in ( + VariablePolicyEntry.TYPE_NO_LOCK, + VariablePolicyEntry.TYPE_LOCK_NOW, + VariablePolicyEntry.TYPE_LOCK_ON_CREATE, + ): result += "\tLock = %s\n" % VariablePolicyEntry.LOCK_POLICY_STRING_MAP[self.LockPolicyType] elif self.LockPolicyType is VariablePolicyEntry.TYPE_LOCK_ON_VAR_STATE: result += "\tLock = %s\n" % self.LockPolicy result += "\tMin = 0x%08X, Max = 0x%08X, Must = 0x%08X, Cant = 0x%08X\n" % ( - self.MinSize, self.MaxSize, self.AttributesMustHave, self.AttributesCantHave) + self.MinSize, + self.MaxSize, + self.AttributesMustHave, + self.AttributesCantHave, + ) return result @staticmethod def csv_header() -> list: """Returns a list containing the names of the ordered columns that are produced by csv_row().""" - return ['Namespace', 'Name', 'LockPolicyType', 'VarStateNamespace', 'VarStateName', - 'VarStateValue', 'MinSize', 'MaxSize', 'AttributesMustHave', 'AttributesCantHave'] + return [ + "Namespace", + "Name", + "LockPolicyType", + "VarStateNamespace", + "VarStateName", + "VarStateValue", + "MinSize", + "MaxSize", + "AttributesMustHave", + "AttributesCantHave", + ] def csv_row(self, guid_xref: dict = None) -> list: """Returns a list containing the elements of this structure. @@ -155,21 +173,31 @@ def csv_row(self, guid_xref: dict = None) -> list: if guid_xref is None: guid_xref = {} - result = [guid_xref.get(self.Namespace, self.Namespace), - self.Name, VariablePolicyEntry.LOCK_POLICY_STRING_MAP[self.LockPolicyType]] - - if self.LockPolicyType in (VariablePolicyEntry.TYPE_NO_LOCK, - VariablePolicyEntry.TYPE_LOCK_NOW, - VariablePolicyEntry.TYPE_LOCK_ON_CREATE): - result += ['N/A', 'N/A', 'N/A'] + result = [ + guid_xref.get(self.Namespace, self.Namespace), + self.Name, + VariablePolicyEntry.LOCK_POLICY_STRING_MAP[self.LockPolicyType], + ] + + if self.LockPolicyType in ( + VariablePolicyEntry.TYPE_NO_LOCK, + VariablePolicyEntry.TYPE_LOCK_NOW, + VariablePolicyEntry.TYPE_LOCK_ON_CREATE, + ): + result += ["N/A", "N/A", "N/A"] elif self.LockPolicyType is VariablePolicyEntry.TYPE_LOCK_ON_VAR_STATE: - result += [guid_xref.get(self.LockPolicy.Namespace, self.LockPolicy.Namespace), - self.LockPolicy.Name, self.LockPolicy.Value] - - result += ["0x%08X" % self.MinSize, - "0x%08X" % self.MaxSize, - str(EfiVariableAttributes(self.AttributesMustHave)), - str(EfiVariableAttributes(self.AttributesCantHave))] + result += [ + guid_xref.get(self.LockPolicy.Namespace, self.LockPolicy.Namespace), + self.LockPolicy.Name, + self.LockPolicy.Value, + ] + + result += [ + "0x%08X" % self.MinSize, + "0x%08X" % self.MaxSize, + str(EfiVariableAttributes(self.AttributesMustHave)), + str(EfiVariableAttributes(self.AttributesCantHave)), + ] return result @@ -179,10 +207,18 @@ def decode(self, buffer: IO) -> bytes: Returns: (bytes): Any remaining buffer """ - (self.Version, self.Size, self.OffsetToName, _namespace, - self.MinSize, self.MaxSize, self.AttributesMustHave, - self.AttributesCantHave, self.LockPolicyType, _) = struct.unpack( - self._HdrStructFormat, buffer[:self._HdrStructSize]) + ( + self.Version, + self.Size, + self.OffsetToName, + _namespace, + self.MinSize, + self.MaxSize, + self.AttributesMustHave, + self.AttributesCantHave, + self.LockPolicyType, + _, + ) = struct.unpack(self._HdrStructFormat, buffer[: self._HdrStructSize]) if self.Version != VariablePolicyEntry.ENTRY_REVISION: raise ValueError("Unknown structure version!") @@ -192,10 +228,10 @@ def decode(self, buffer: IO) -> bytes: self.Namespace = uuid.UUID(bytes_le=_namespace) if self.OffsetToName != self.Size: - self.Name = buffer[self.OffsetToName:self.Size].decode('utf-16').strip('\x00') + self.Name = buffer[self.OffsetToName : self.Size].decode("utf-16").strip("\x00") if self.LockPolicyType == VariablePolicyEntry.TYPE_LOCK_ON_VAR_STATE: self.LockPolicy = VariableLockOnVarStatePolicy() - self.LockPolicy.decode(buffer[self._HdrStructSize:self.OffsetToName]) + self.LockPolicy.decode(buffer[self._HdrStructSize : self.OffsetToName]) - return buffer[self.Size:] + return buffer[self.Size :] diff --git a/edk2toollib/uefi/edk2/variablestore_manulipulations.py b/edk2toollib/uefi/edk2/variablestore_manulipulations.py index 0e661ce3..82aaab43 100644 --- a/edk2toollib/uefi/edk2/variablestore_manulipulations.py +++ b/edk2toollib/uefi/edk2/variablestore_manulipulations.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Contains classes and helper functions to modify variables in a UEFI ROM image.""" + import mmap import os from typing import Optional @@ -16,7 +17,10 @@ class VariableStore(object): """Class representing the variable store.""" - def __init__(self, romfile: str, store_base: Optional[int]=None, store_size: Optional[int]=None) -> 'VariableStore': + + def __init__( + self, romfile: str, store_base: Optional[int] = None, store_size: Optional[int] = None + ) -> "VariableStore": """Initialize the Variable store and read necessary files. Loads the data. @@ -30,12 +34,12 @@ def __init__(self, romfile: str, store_base: Optional[int]=None, store_size: Opt if not os.path.isfile(self.rom_file_path): raise Exception("'%s' is not the path to a file!" % self.rom_file_path) - self.rom_file = open(self.rom_file_path, 'r+b') + self.rom_file = open(self.rom_file_path, "r+b") self.rom_file_map = mmap.mmap(self.rom_file.fileno(), 0) # Sanity check some things. file_size = self.rom_file_map.size() - if (store_base is not None and store_size is not None and (store_base + store_size) > file_size): + if store_base is not None and store_size is not None and (store_base + store_size) > file_size: raise Exception("ROM file is %d bytes. Cannot seek to %d+%d bytes!" % (file_size, store_base, store_size)) # Go ahead and advance the file cursor and load the FV header. @@ -49,8 +53,10 @@ def __init__(self, romfile: str, store_base: Optional[int]=None, store_size: Opt # Advance the file cursor and load the VarStore header. self.rom_file.seek(self.fv_header.HeaderLength, os.SEEK_CUR) self.var_store_header = VF.VariableStoreHeader().load_from_file(self.rom_file) - if self.var_store_header.Format != VF.VARIABLE_STORE_FORMATTED or \ - self.var_store_header.State != VF.VARIABLE_STORE_HEALTHY: + if ( + self.var_store_header.Format != VF.VARIABLE_STORE_FORMATTED + or self.var_store_header.State != VF.VARIABLE_STORE_HEALTHY + ): raise Exception("VarStore is invalid or cannot be processed with this helper!") # Now we're finally ready to read some variables. @@ -84,7 +90,7 @@ def __del__(self) -> None: def get_new_var_class(self) -> VF.VariableHeader | VF.AuthenticatedVariableHeader: """Var class builder method depending on var type.""" - if self.var_store_header.Type == 'Var': + if self.var_store_header.Type == "Var": new_var = VF.VariableHeader() else: new_var = VF.AuthenticatedVariableHeader() @@ -103,18 +109,19 @@ def flush_to_file(self) -> None: dummy_var = self.get_new_var_class() var_size += dummy_var.StructSize if var_size > self.var_store_header.Size: - raise Exception("Total variable size %d is too large to fit in VarStore %d!" % - (var_size, self.var_store_header.Size)) + raise Exception( + "Total variable size %d is too large to fit in VarStore %d!" % (var_size, self.var_store_header.Size) + ) # Now, we just have to serialize each variable in turn and write them to the mmap buffer. var_offset = self.store_base + self.fv_header.HeaderLength + self.var_store_header.StructSize for var in self.variables: var_buffer_size = var.get_buffer_size() - self.rom_file_map[var_offset:(var_offset + var_buffer_size)] = var.serialize(True) + self.rom_file_map[var_offset : (var_offset + var_buffer_size)] = var.serialize(True) var_offset += var_buffer_size # Add a terminating Variable Header. - self.rom_file_map[var_offset:(var_offset + dummy_var.StructSize)] = b'\xFF' * dummy_var.StructSize + self.rom_file_map[var_offset : (var_offset + dummy_var.StructSize)] = b"\xff" * dummy_var.StructSize # Now we have to flush the mmap to the file. self.rom_file_map.flush() diff --git a/edk2toollib/uefi/fmp_auth_header.py b/edk2toollib/uefi/fmp_auth_header.py index 40912367..baf271e0 100644 --- a/edk2toollib/uefi/fmp_auth_header.py +++ b/edk2toollib/uefi/fmp_auth_header.py @@ -16,7 +16,7 @@ from edk2toollib.uefi.wincert import WinCertUefiGuid -class FmpAuthHeaderClass (object): +class FmpAuthHeaderClass(object): r"""An object representing an EFI_FIRMWARE_IMAGE_AUTHENTICATION. Can parse or produce an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure/byte buffer. @@ -35,14 +35,15 @@ class FmpAuthHeaderClass (object): } EFI_FIRMWARE_IMAGE_AUTHENTICATION; ``` """ - _MonotonicCountFormat = ' 'FmpAuthHeaderClass': + def __init__(self) -> "FmpAuthHeaderClass": """Inits an empty object.""" self.MonotonicCount = 0 self.AuthInfo = WinCertUefiGuid() - self.Payload = b'' + self.Payload = b"" self.FmpPayloadHeader = None def Encode(self) -> bytes: @@ -51,10 +52,7 @@ def Encode(self) -> bytes: Returns: (bytes): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - FmpAuthHeader = struct.pack( - self._MonotonicCountFormat, - self.MonotonicCount - ) + FmpAuthHeader = struct.pack(self._MonotonicCountFormat, self.MonotonicCount) if self.FmpPayloadHeader is not None: return FmpAuthHeader + self.AuthInfo.Encode() + self.FmpPayloadHeader.Encode() @@ -75,13 +73,10 @@ def Decode(self, Buffer: IO) -> bytes: """ if len(Buffer) < self._MonotonicCountSize: raise ValueError - (MonotonicCount,) = struct.unpack( - self._MonotonicCountFormat, - Buffer[:self._MonotonicCountSize] - ) + (MonotonicCount,) = struct.unpack(self._MonotonicCountFormat, Buffer[: self._MonotonicCountSize]) self.MonotonicCount = MonotonicCount - self.Payload = self.AuthInfo.Decode(Buffer[self._MonotonicCountSize:]) + self.Payload = self.AuthInfo.Decode(Buffer[self._MonotonicCountSize :]) if len(self.Payload) > 0: self.FmpPayloadHeader = FmpPayloadHeaderClass() self.FmpPayloadHeader.Decode(self.Payload) @@ -98,17 +93,23 @@ def IsSigned(self, Buffer: IO) -> bool: if len(Buffer) < self._MonotonicCountSize: return False - auth_info = WinCertUefiGuid(Buffer[self._MonotonicCountSize:]) + auth_info = WinCertUefiGuid(Buffer[self._MonotonicCountSize :]) if auth_info.CertType != WinCertUefiGuid._EFI_CERT_TYPE_PKCS7_GUID.bytes_le: return False return True def DumpInfo(self) -> None: """Prints object to console.""" - print('EFI_FIRMWARE_IMAGE_AUTHENTICATION.MonotonicCount = {MonotonicCount:016X}' - .format(MonotonicCount=self.MonotonicCount)) + print( + "EFI_FIRMWARE_IMAGE_AUTHENTICATION.MonotonicCount = {MonotonicCount:016X}".format( + MonotonicCount=self.MonotonicCount + ) + ) self.AuthInfo.DumpInfo() - print('sizeof (Payload) = {Size:08X}' - .format(Size=len(self.Payload))) + print( + "sizeof (Payload) = {Size:08X}".format( + Size=len(self.Payload) + ) + ) if self.FmpPayloadHeader is not None: self.FmpPayloadHeader.DumpInfo() diff --git a/edk2toollib/uefi/fmp_capsule_header.py b/edk2toollib/uefi/fmp_capsule_header.py index 43b20c0e..31ceee8a 100644 --- a/edk2toollib/uefi/fmp_capsule_header.py +++ b/edk2toollib/uefi/fmp_capsule_header.py @@ -15,7 +15,7 @@ from edk2toollib.uefi.fmp_auth_header import FmpAuthHeaderClass -class FmpCapsuleImageHeaderClass (object): +class FmpCapsuleImageHeaderClass(object): r"""An object representing an EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER. Can parse or produce an EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER structure/byte buffer. @@ -47,21 +47,22 @@ class FmpCapsuleImageHeaderClass (object): #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000002 ``` """ - _StructFormat = ' 'FmpCapsuleImageHeaderClass': + def __init__(self) -> "FmpCapsuleImageHeaderClass": """Inits an empty object.""" self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION - self.UpdateImageTypeId = uuid.UUID('00000000-0000-0000-0000-000000000000') + self.UpdateImageTypeId = uuid.UUID("00000000-0000-0000-0000-000000000000") self.UpdateImageIndex = 0 self.UpdateImageSize = 0 self.UpdateVendorCodeSize = 0 self.UpdateHardwareInstance = 0x0000000000000000 - self.Payload = b'' - self.VendorCodeBytes = b'' + self.Payload = b"" + self.VendorCodeBytes = b"" self.FmpAuthHeader = None def Encode(self) -> bytes: @@ -81,10 +82,12 @@ def Encode(self) -> bytes: self.Version, self.UpdateImageTypeId.bytes_le, self.UpdateImageIndex, - 0, 0, 0, + 0, + 0, + 0, self.UpdateImageSize, self.UpdateVendorCodeSize, - self.UpdateHardwareInstance + self.UpdateHardwareInstance, ) return FmpCapsuleImageHeader + self.Payload + self.VendorCodeBytes @@ -103,17 +106,23 @@ def Decode(self, Buffer: IO) -> bytes: """ if len(Buffer) < self._StructSize: raise ValueError - (Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2, - UpdateImageSize, UpdateVendorCodeSize, UpdateHardwareInstance) = struct.unpack( - self._StructFormat, - Buffer[0:self._StructSize] - ) + ( + Version, + UpdateImageTypeId, + UpdateImageIndex, + r0, + r1, + r2, + UpdateImageSize, + UpdateVendorCodeSize, + UpdateHardwareInstance, + ) = struct.unpack(self._StructFormat, Buffer[0 : self._StructSize]) if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION: raise ValueError if UpdateImageIndex < 1: raise ValueError - if UpdateImageSize + UpdateVendorCodeSize != len(Buffer[self._StructSize:]): + if UpdateImageSize + UpdateVendorCodeSize != len(Buffer[self._StructSize :]): raise ValueError self.Version = Version @@ -122,36 +131,60 @@ def Decode(self, Buffer: IO) -> bytes: self.UpdateImageSize = UpdateImageSize self.UpdateVendorCodeSize = UpdateVendorCodeSize self.UpdateHardwareInstance = UpdateHardwareInstance - self.Payload = Buffer[self._StructSize:self._StructSize + UpdateImageSize] + self.Payload = Buffer[self._StructSize : self._StructSize + UpdateImageSize] if len(self.Payload) > 0: self.FmpAuthHeader = FmpAuthHeaderClass() self.FmpAuthHeader.Decode(self.Payload) - self.VendorCodeBytes = Buffer[self._StructSize + UpdateImageSize:] - return Buffer[self._StructSize:] + self.VendorCodeBytes = Buffer[self._StructSize + UpdateImageSize :] + return Buffer[self._StructSize :] def DumpInfo(self) -> None: """Prints object to Console.""" - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}' - .format(Version=self.Version)) - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}' - .format(UpdateImageTypeId=str(self.UpdateImageTypeId).upper())) - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}' - .format(UpdateImageIndex=self.UpdateImageIndex)) - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}' - .format(UpdateImageSize=self.UpdateImageSize)) - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}' - .format(UpdateVendorCodeSize=self.UpdateVendorCodeSize)) - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}' - .format(UpdateHardwareInstance=self.UpdateHardwareInstance)) - print('sizeof (Payload) = {Size:08X}' - .format(Size=len(self.Payload))) - print('sizeof (VendorCodeBytes) = {Size:08X}' - .format(Size=len(self.VendorCodeBytes))) + print( + "EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}".format( + Version=self.Version + ) + ) + print( + "EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}".format( + UpdateImageTypeId=str(self.UpdateImageTypeId).upper() + ) + ) + print( + "EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}".format( + UpdateImageIndex=self.UpdateImageIndex + ) + ) + print( + "EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}".format( + UpdateImageSize=self.UpdateImageSize + ) + ) + print( + "EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}".format( + UpdateVendorCodeSize=self.UpdateVendorCodeSize + ) + ) + print( + "EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}".format( + UpdateHardwareInstance=self.UpdateHardwareInstance + ) + ) + print( + "sizeof (Payload) = {Size:08X}".format( + Size=len(self.Payload) + ) + ) + print( + "sizeof (VendorCodeBytes) = {Size:08X}".format( + Size=len(self.VendorCodeBytes) + ) + ) if self.FmpAuthHeader is not None: self.FmpAuthHeader.DumpInfo() -class FmpCapsuleHeaderClass (object): +class FmpCapsuleHeaderClass(object): """An object representing a EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION. Can parse or produce an EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION structure/byte buffer. @@ -173,15 +206,16 @@ class FmpCapsuleHeaderClass (object): #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION 0x00000001 ``` """ - _StructFormat = ' 'FmpCapsuleHeaderClass': + def __init__(self) -> "FmpCapsuleHeaderClass": """Inits an empty object.""" self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION self.EmbeddedDriverCount = 0 @@ -198,12 +232,12 @@ def GetEmbeddedDriver(self, Index: int) -> bytes: """Returns the embedded driver at the index.""" return self._EmbeddedDriverList[Index] - def AddFmpCapsuleImageHeader(self, FmpCapsuleHeader: 'FmpCapsuleImageHeaderClass') -> None: + def AddFmpCapsuleImageHeader(self, FmpCapsuleHeader: "FmpCapsuleImageHeaderClass") -> None: """Adds an Fmp Capsule Image header to the list.""" self._FmpCapsuleImageHeaderList.append(FmpCapsuleHeader) self.PayloadItemCount += 1 - def GetFmpCapsuleImageHeader(self, Index: int) -> 'FmpCapsuleImageHeaderClass': + def GetFmpCapsuleImageHeader(self, Index: int) -> "FmpCapsuleImageHeaderClass": """Returns the Fmp Capsule Image header at the index.""" return self._FmpCapsuleImageHeaderList[Index] @@ -217,13 +251,10 @@ def Encode(self) -> bytes: self.PayloadItemCount = len(self._FmpCapsuleImageHeaderList) FmpCapsuleHeader = struct.pack( - self._StructFormat, - self.Version, - self.EmbeddedDriverCount, - self.PayloadItemCount + self._StructFormat, self.Version, self.EmbeddedDriverCount, self.PayloadItemCount ) - FmpCapsuleData = b'' + FmpCapsuleData = b"" offset_list = [] Offset = self._StructSize + (self.EmbeddedDriverCount + self.PayloadItemCount) * self._ItemOffsetSize for EmbeddedDriver in self._EmbeddedDriverList: @@ -257,8 +288,7 @@ def Decode(self, Buffer: IO) -> bytes: if len(Buffer) < self._StructSize: raise ValueError (Version, EmbeddedDriverCount, PayloadItemCount) = struct.unpack( - self._StructFormat, - Buffer[0:self._StructSize] + self._StructFormat, Buffer[0 : self._StructSize] ) if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION: raise ValueError @@ -276,7 +306,7 @@ def Decode(self, Buffer: IO) -> bytes: # Offset = self._StructSize for Index in range(EmbeddedDriverCount + PayloadItemCount): - ItemOffset = struct.unpack(self._ItemOffsetFormat, Buffer[Offset:Offset + self._ItemOffsetSize])[0] + ItemOffset = struct.unpack(self._ItemOffsetFormat, Buffer[Offset : Offset + self._ItemOffsetSize])[0] if ItemOffset >= len(Buffer): raise ValueError offset_list.append(ItemOffset) @@ -292,7 +322,7 @@ def Decode(self, Buffer: IO) -> bytes: Length = offset_list[Index + 1] - Offset else: Length = len(Buffer) - Offset - self.AddEmbeddedDriver(Buffer[Offset:Offset + Length]) + self.AddEmbeddedDriver(Buffer[Offset : Offset + Length]) # # Parse the Payloads that are FMP Capsule Images @@ -304,21 +334,30 @@ def Decode(self, Buffer: IO) -> bytes: else: Length = len(Buffer) - Offset FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass() - FmpCapsuleImageHeader.Decode(Buffer[Offset:Offset + Length]) + FmpCapsuleImageHeader.Decode(Buffer[Offset : Offset + Length]) self.AddFmpCapsuleImageHeader(FmpCapsuleImageHeader) return Result def DumpInfo(self) -> None: """Prints the object to the console.""" - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}'.format(Version=self.Version)) - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format( - EmbeddedDriverCount=self.EmbeddedDriverCount)) + print("EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}".format(Version=self.Version)) + print( + "EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}".format( + EmbeddedDriverCount=self.EmbeddedDriverCount + ) + ) for EmbeddedDriver in self._EmbeddedDriverList: - print(' sizeof (EmbeddedDriver) = {Size:08X}'.format( - Size=len(EmbeddedDriver))) - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = {PayloadItemCount:08X}'.format( - PayloadItemCount=self.PayloadItemCount)) - print('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = ') + print( + " sizeof (EmbeddedDriver) = {Size:08X}".format( + Size=len(EmbeddedDriver) + ) + ) + print( + "EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = {PayloadItemCount:08X}".format( + PayloadItemCount=self.PayloadItemCount + ) + ) + print("EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = ") for FmpCapsuleImageHeader in self._FmpCapsuleImageHeaderList: FmpCapsuleImageHeader.DumpInfo() diff --git a/edk2toollib/uefi/pi_firmware_file.py b/edk2toollib/uefi/pi_firmware_file.py index 748147b5..fbcd764d 100644 --- a/edk2toollib/uefi/pi_firmware_file.py +++ b/edk2toollib/uefi/pi_firmware_file.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Module containing helper classes and functions for working with UEFI FFs.""" + import struct import sys import uuid @@ -28,7 +29,8 @@ class EfiFirmwareFileSystemHeader(object): } EFI_FFS_FILE_HEADER; ``` """ - def __init__(self) -> 'EfiFirmwareFileSystemHeader': + + def __init__(self) -> "EfiFirmwareFileSystemHeader": """Inits an empty object.""" self.StructString = "=16sHBBBBBB" # spell-checker: disable-line self.FileSystemGuid = None @@ -43,7 +45,7 @@ def get_size(self) -> int: """Returns the size of the header.""" return self.Size0 + (self.Size1 << 8) + (self.Size2 << 16) - def load_from_file(self, file: IO) -> 'EfiFirmwareFileSystemHeader': + def load_from_file(self, file: IO) -> "EfiFirmwareFileSystemHeader": """Loads data into the object from a filestream. Args: @@ -57,11 +59,19 @@ def load_from_file(self, file: IO) -> 'EfiFirmwareFileSystemHeader': file.seek(orig_seek) # Load this object with the contents of the data. - (self.FileSystemGuid, self.Checksum, self.Type, self.Attributes, self.Size0, self.Size1, - self.Size2, self.State) = struct.unpack(self.StructString, struct_bytes) + ( + self.FileSystemGuid, + self.Checksum, + self.Type, + self.Attributes, + self.Size0, + self.Size1, + self.Size2, + self.State, + ) = struct.unpack(self.StructString, struct_bytes) # Update the GUID to be a UUID object. - if sys.byteorder == 'big': + if sys.byteorder == "big": self.FileSystemGuid = uuid.UUID(bytes=self.FileSystemGuid) else: self.FileSystemGuid = uuid.UUID(bytes_le=self.FileSystemGuid) @@ -74,6 +84,15 @@ def serialize(self) -> bytes: Returns: (bytes): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - file_system_guid_bin = self.FileSystemGuid.bytes if sys.byteorder == 'big' else self.FileSystemGuid.bytes_le - return struct.pack(self.StructString, file_system_guid_bin, self.Checksum, - self.Type, self.Attributes, self.Size0, self.Size1, self.Size2, self.State) + file_system_guid_bin = self.FileSystemGuid.bytes if sys.byteorder == "big" else self.FileSystemGuid.bytes_le + return struct.pack( + self.StructString, + file_system_guid_bin, + self.Checksum, + self.Type, + self.Attributes, + self.Size0, + self.Size1, + self.Size2, + self.State, + ) diff --git a/edk2toollib/uefi/pi_firmware_volume.py b/edk2toollib/uefi/pi_firmware_volume.py index 9e270b6a..76411055 100644 --- a/edk2toollib/uefi/pi_firmware_volume.py +++ b/edk2toollib/uefi/pi_firmware_volume.py @@ -46,7 +46,8 @@ class EfiFirmwareVolumeHeader(object): } EFI_FIRMWARE_VOLUME_HEADER; ``` """ - def __init__(self) -> 'EfiFirmwareVolumeHeader': + + def __init__(self) -> "EfiFirmwareVolumeHeader": """Inits an empty object.""" self.StructString = "=16s16sQ4sLHHHBBQQ" # spell-checker: disable-line self.ZeroVector = None @@ -61,7 +62,7 @@ def __init__(self) -> 'EfiFirmwareVolumeHeader': self.Blockmap0 = None self.Blockmap1 = None - def load_from_file(self, file: IO) -> 'EfiFirmwareVolumeHeader': + def load_from_file(self, file: IO) -> "EfiFirmwareVolumeHeader": """Loads data into the object from a filestream. Args: @@ -80,16 +81,27 @@ def load_from_file(self, file: IO) -> 'EfiFirmwareVolumeHeader': file.seek(orig_seek) # Load this object with the contents of the data. - (self.ZeroVector, file_system_guid_bin, self.FvLength, self.Signature, self.Attributes, - self.HeaderLength, self.Checksum, self.ExtHeaderOffset, self.Reserved, self.Revision, - self.Blockmap0, self.Blockmap1) = struct.unpack(self.StructString, struct_bytes) + ( + self.ZeroVector, + file_system_guid_bin, + self.FvLength, + self.Signature, + self.Attributes, + self.HeaderLength, + self.Checksum, + self.ExtHeaderOffset, + self.Reserved, + self.Revision, + self.Blockmap0, + self.Blockmap1, + ) = struct.unpack(self.StructString, struct_bytes) # Make sure that this structure is what we think it is. if self.Signature != EFI_FVH_SIGNATURE: raise Exception("File does not appear to point to a valid EfiFirmwareVolumeHeader!") # Update the GUID to be a UUID object. - if sys.byteorder == 'big': + if sys.byteorder == "big": self.FileSystemGuid = uuid.UUID(bytes=file_system_guid_bin) else: self.FileSystemGuid = uuid.UUID(bytes_le=file_system_guid_bin) @@ -102,10 +114,22 @@ def serialize(self) -> bytes: Returns: (str): string representing packed data as bytes (i.e. b'\x01\x00\x03') """ - file_system_guid_bin = self.FileSystemGuid.bytes if sys.byteorder == 'big' else self.FileSystemGuid.bytes_le - return struct.pack(self.StructString, self.ZeroVector, file_system_guid_bin, self.FvLength, self.Signature, - self.Attributes, self.HeaderLength, self.Checksum, self.ExtHeaderOffset, self.Reserved, - self.Revision, self.Blockmap0, self.Blockmap1) + file_system_guid_bin = self.FileSystemGuid.bytes if sys.byteorder == "big" else self.FileSystemGuid.bytes_le + return struct.pack( + self.StructString, + self.ZeroVector, + file_system_guid_bin, + self.FvLength, + self.Signature, + self.Attributes, + self.HeaderLength, + self.Checksum, + self.ExtHeaderOffset, + self.Reserved, + self.Revision, + self.Blockmap0, + self.Blockmap1, + ) class EfiFirmwareVolumeExtHeader(object): @@ -120,13 +144,14 @@ class EfiFirmwareVolumeExtHeader(object): } EFI_FIRMWARE_VOLUME_EXT_HEADER; ``` """ - def __init__(self) -> 'EfiFirmwareVolumeExtHeader': + + def __init__(self) -> "EfiFirmwareVolumeExtHeader": """Inits an empty object.""" self.StructString = "=16sL" self.FileSystemGuid = None self.ExtHeaderSize = None - def load_from_file(self, file: IO) -> 'EfiFirmwareVolumeExtHeader': + def load_from_file(self, file: IO) -> "EfiFirmwareVolumeExtHeader": """Loads data into the object from a filestream. Args: diff --git a/edk2toollib/uefi/status_codes.py b/edk2toollib/uefi/status_codes.py index 176ed836..8d57e304 100644 --- a/edk2toollib/uefi/status_codes.py +++ b/edk2toollib/uefi/status_codes.py @@ -12,16 +12,55 @@ class UefiStatusCode(object): """Object representing a UEFI Status Code from Appendix D of the UEFI spec.""" # high bit set - ErrorCodeStrings = ["NOT VALID", "Load Error", "Invalid Parameter", "Unsupported", "Bad BufferSize", - "Buffer Too Small", "Not Ready", "Device Error", "Write Protected", "Out of Resources", - "Volume Corrupt", "Volume Full", "No Media", "Media Changed", "Not Found", "Access Denied", - "No Response", "No Mapping", "Time Out", "Not Started", "Already Started", "Aborted", - "ICMP Error", "TFTP Error", "Protocol Error", "Incompatible Error", "Security Violation", - "CRC Error", "End of Media", "Reserved(29)", "Reserved(30)", "End of File", - "Invalid Language", "Compromised Data", "IP Address Conflict", "HTTP Error"] + ErrorCodeStrings = [ + "NOT VALID", + "Load Error", + "Invalid Parameter", + "Unsupported", + "Bad BufferSize", + "Buffer Too Small", + "Not Ready", + "Device Error", + "Write Protected", + "Out of Resources", + "Volume Corrupt", + "Volume Full", + "No Media", + "Media Changed", + "Not Found", + "Access Denied", + "No Response", + "No Mapping", + "Time Out", + "Not Started", + "Already Started", + "Aborted", + "ICMP Error", + "TFTP Error", + "Protocol Error", + "Incompatible Error", + "Security Violation", + "CRC Error", + "End of Media", + "Reserved(29)", + "Reserved(30)", + "End of File", + "Invalid Language", + "Compromised Data", + "IP Address Conflict", + "HTTP Error", + ] - NonErrorCodeStrings = ["Success", "Unknown Glyph", "Delete Failure", "Write Failure", "Buffer Too Small", - "Stale Data", "File System", "Reset Required"] + NonErrorCodeStrings = [ + "Success", + "Unknown Glyph", + "Delete Failure", + "Write Failure", + "Buffer Too Small", + "Stale Data", + "File System", + "Reset Required", + ] def Convert32BitToString(self, value: int) -> str: """Convert 32 bit int to a friendly UEFI status code string value.""" @@ -32,7 +71,7 @@ def Convert32BitToString(self, value: int) -> str: StatusStrings = UefiStatusCode.ErrorCodeStrings value = value & 0x7FFFFFFF # mask off upper bit - if (value >= len(StatusStrings)): + if value >= len(StatusStrings): return "Undefined StatusCode" return StatusStrings[value] @@ -46,7 +85,7 @@ def Convert64BitToString(self, value: int) -> str: StatusStrings = UefiStatusCode.ErrorCodeStrings value = value & 0x7FFFFFFFFFFFFFFF # mask off upper bit - if (value >= len(StatusStrings)): + if value >= len(StatusStrings): return "Undefined StatusCode" return StatusStrings[value] diff --git a/edk2toollib/uefi/uefi_capsule_header.py b/edk2toollib/uefi/uefi_capsule_header.py index 3db0a631..4699798c 100644 --- a/edk2toollib/uefi/uefi_capsule_header.py +++ b/edk2toollib/uefi/uefi_capsule_header.py @@ -13,7 +13,7 @@ from edk2toollib.uefi.fmp_capsule_header import FmpCapsuleHeaderClass -class UefiCapsuleHeaderClass (object): +class UefiCapsuleHeaderClass(object): r"""An object representing a UEFI_CAPSULE_HEADER. Attributes: @@ -42,16 +42,17 @@ class UefiCapsuleHeaderClass (object): #define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 ``` """ - _StructFormat = '<16sIIII' + + _StructFormat = "<16sIIII" _StructSize = struct.calcsize(_StructFormat) - EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID = uuid.UUID('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A') + EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID = uuid.UUID("6DCBD5ED-E82D-4C44-BDA1-7194199AD92A") _CAPSULE_FLAGS_PERSIST_ACROSS_RESET = 0x00010000 _CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE = 0x00020000 _CAPSULE_FLAGS_INITIATE_RESET = 0x00040000 - def __init__(self) -> 'UefiCapsuleHeaderClass': + def __init__(self) -> "UefiCapsuleHeaderClass": """Inits an empty object.""" self.CapsuleGuid = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID self.HeaderSize = self._StructSize @@ -60,7 +61,7 @@ def __init__(self) -> 'UefiCapsuleHeaderClass': self.PopulateSystemTable = False self.InitiateReset = False self.CapsuleImageSize = self.HeaderSize - self.Payload = b'' + self.Payload = b"" self.FmpCapsuleHeader = None def Encode(self) -> bytes: @@ -84,12 +85,7 @@ def Encode(self) -> bytes: self.CapsuleImageSize = self.HeaderSize + len(self.Payload) UefiCapsuleHeader = struct.pack( - self._StructFormat, - self.CapsuleGuid.bytes_le, - self.HeaderSize, - Flags, - self.CapsuleImageSize, - 0 + self._StructFormat, self.CapsuleGuid.bytes_le, self.HeaderSize, Flags, self.CapsuleImageSize, 0 ) return UefiCapsuleHeader + self.Payload @@ -111,8 +107,7 @@ def Decode(self, Buffer: BytesIO) -> bytes: if len(Buffer) < self._StructSize: raise ValueError (CapsuleGuid, HeaderSize, Flags, CapsuleImageSize, Reserved) = struct.unpack( - self._StructFormat, - Buffer[0:self._StructSize] + self._StructFormat, Buffer[0 : self._StructSize] ) if HeaderSize < self._StructSize: raise ValueError @@ -120,12 +115,12 @@ def Decode(self, Buffer: BytesIO) -> bytes: raise ValueError self.CapsuleGuid = uuid.UUID(bytes_le=CapsuleGuid) self.HeaderSize = HeaderSize - self.OemFlags = Flags & 0xffff + self.OemFlags = Flags & 0xFFFF self.PersistAcrossReset = (Flags & self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0 self.PopulateSystemTable = (Flags & self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0 self.InitiateReset = (Flags & self._CAPSULE_FLAGS_INITIATE_RESET) != 0 self.CapsuleImageSize = CapsuleImageSize - self.Payload = Buffer[self.HeaderSize:] + self.Payload = Buffer[self.HeaderSize :] if len(self.Payload) > 0 and self.CapsuleGuid == self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID: self.FmpCapsuleHeader = FmpCapsuleHeaderClass() self.FmpCapsuleHeader.Decode(self.Payload) @@ -141,17 +136,17 @@ def DumpInfo(self) -> None: Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE if self.InitiateReset: Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET - print('EFI_CAPSULE_HEADER.CapsuleGuid = {Guid}'.format(Guid=str(self.CapsuleGuid).upper())) - print('EFI_CAPSULE_HEADER.HeaderSize = {Size:08X}'.format(Size=self.HeaderSize)) - print('EFI_CAPSULE_HEADER.Flags = {Flags:08X}'.format(Flags=Flags)) - print(' OEM Flags = {Flags:04X}'.format(Flags=self.OemFlags)) + print("EFI_CAPSULE_HEADER.CapsuleGuid = {Guid}".format(Guid=str(self.CapsuleGuid).upper())) + print("EFI_CAPSULE_HEADER.HeaderSize = {Size:08X}".format(Size=self.HeaderSize)) + print("EFI_CAPSULE_HEADER.Flags = {Flags:08X}".format(Flags=Flags)) + print(" OEM Flags = {Flags:04X}".format(Flags=self.OemFlags)) if self.PersistAcrossReset: - print(' CAPSULE_FLAGS_PERSIST_ACROSS_RESET') + print(" CAPSULE_FLAGS_PERSIST_ACROSS_RESET") if self.PopulateSystemTable: - print(' CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE') + print(" CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE") if self.InitiateReset: - print(' CAPSULE_FLAGS_INITIATE_RESET') - print('EFI_CAPSULE_HEADER.CapsuleImageSize = {Size:08X}'.format(Size=self.CapsuleImageSize)) - print('sizeof (Payload) = {Size:08X}'.format(Size=len(self.Payload))) + print(" CAPSULE_FLAGS_INITIATE_RESET") + print("EFI_CAPSULE_HEADER.CapsuleImageSize = {Size:08X}".format(Size=self.CapsuleImageSize)) + print("sizeof (Payload) = {Size:08X}".format(Size=len(self.Payload))) if self.FmpCapsuleHeader is not None: self.FmpCapsuleHeader.DumpInfo() diff --git a/edk2toollib/uefi/uefi_multi_phase.py b/edk2toollib/uefi/uefi_multi_phase.py index 33441b77..9d613ff2 100644 --- a/edk2toollib/uefi/uefi_multi_phase.py +++ b/edk2toollib/uefi/uefi_multi_phase.py @@ -33,7 +33,7 @@ class EfiVariableAttributes(object): EFI_VARIABLE_HARDWARE_ERROR_RECORD: "HW", EFI_VARIABLE_RUNTIME_ACCESS: "RT", EFI_VARIABLE_BOOTSERVICE_ACCESS: "BS", - EFI_VARIABLE_NON_VOLATILE: "NV" + EFI_VARIABLE_NON_VOLATILE: "NV", } INVERSE_SHORT_STRING_MAP = {v: k for k, v in SHORT_STRING_MAP.items()} @@ -48,7 +48,7 @@ class EfiVariableAttributes(object): } INVERSE_STRING_MAP = {v: k for k, v in STRING_MAP.items()} - def __init__(self, attributes: Union[int, str]=0x0000_0000, decodefs: IO=None) -> 'EfiVariableAttributes': + def __init__(self, attributes: Union[int, str] = 0x0000_0000, decodefs: IO = None) -> "EfiVariableAttributes": """Creates a EfiVariableAttributes object. Args: @@ -80,8 +80,7 @@ def update(self, attributes: Union[int, str] = 0x0000_00000) -> None: elif isinstance(attributes, str): self.attributes = EfiVariableAttributes.parse_attributes_str(attributes) else: - raise TypeError( - f"Invalid type: {type(attributes)}") + raise TypeError(f"Invalid type: {type(attributes)}") @staticmethod def parse_attributes_str(attributes_str: str) -> int: @@ -110,12 +109,14 @@ def parse_attributes_str(attributes_str: str) -> int: attributes_str = attributes_str.replace(" ", "") # Loop over all the attributes - for attr in attributes_str.split(','): + for attr in attributes_str.split(","): attr = attr.upper() # convert to upper for consistency - if attr not in EfiVariableAttributes.INVERSE_STRING_MAP \ - and attr not in EfiVariableAttributes.INVERSE_SHORT_STRING_MAP: - raise ValueError(f"Attribute string \"{attr}\" not supported") + if ( + attr not in EfiVariableAttributes.INVERSE_STRING_MAP + and attr not in EfiVariableAttributes.INVERSE_SHORT_STRING_MAP + ): + raise ValueError(f'Attribute string "{attr}" not supported') # attempt to get the value from the INVERSE_STRING_MAP if it fails, # try to grab it from the INVERSE_SHORT_MAP @@ -123,8 +124,8 @@ def parse_attributes_str(attributes_str: str) -> int: attr, EfiVariableAttributes.INVERSE_SHORT_STRING_MAP.get( attr, - 0 # We should never get here since it would fail the above if condition - ) + 0, # We should never get here since it would fail the above if condition + ), ) attributes |= attr_value @@ -155,7 +156,9 @@ def decode(self, fs: IO) -> int: return attributes - def encode(self,) -> bytes: + def encode( + self, + ) -> bytes: """Returns the attributes as a packed structure. !!! Examples @@ -172,7 +175,9 @@ def encode(self,) -> bytes: """ return struct.pack(EfiVariableAttributes._struct_format, self.attributes) - def get_short_string(self,) -> str: + def get_short_string( + self, + ) -> str: """Short form string representation of the attributes. !!! Examples @@ -191,7 +196,9 @@ def get_short_string(self,) -> str: result.append(EfiVariableAttributes.SHORT_STRING_MAP[key]) return ",".join(result) - def __str__(self,) -> str: + def __str__( + self, + ) -> str: """String representation of the attributes. Returns: @@ -203,6 +210,8 @@ def __str__(self,) -> str: result.append(EfiVariableAttributes.STRING_MAP[key]) return ",".join(result) - def __int__(self,) -> int: + def __int__( + self, + ) -> int: """Returns attributes as an int.""" return self.attributes diff --git a/edk2toollib/uefi/wincert.py b/edk2toollib/uefi/wincert.py index 47da9611..791275e3 100644 --- a/edk2toollib/uefi/wincert.py +++ b/edk2toollib/uefi/wincert.py @@ -8,7 +8,6 @@ """Module for working with UEFI WinCert data.""" - import io import struct import sys @@ -55,10 +54,11 @@ class WinCertPkcs1(object): UINT8 bCertificate[ANYSIZE_ARRAY]; } WIN_CERTIFICATE; """ - STATIC_STRUCT_SIZE = (4 + 2 + 2 + 16) + + STATIC_STRUCT_SIZE = 4 + 2 + 2 + 16 EFI_HASH_SHA256 = uuid.UUID("{51AA59DE-FDF2-4EA3-BC63-875FB7842EE9}") # EFI_HASH_SHA256 guid defined by UEFI spec - def __init__(self, filestream: Optional[BytesIO]=None) -> 'WinCertPkcs1': + def __init__(self, filestream: Optional[BytesIO] = None) -> "WinCertPkcs1": """Inits the object.""" if filestream is None: self.Hdr_dwLength = WinCertPkcs1.STATIC_STRUCT_SIZE @@ -140,7 +140,7 @@ def decode(self, fs: BytesIO) -> None: (ValueError): Invalid stream (ValueError): Invalid stream size """ - if (fs is None): + if fs is None: raise ValueError("Invalid File stream") # only populate from file stream those parts that are complete in the file stream @@ -149,7 +149,7 @@ def decode(self, fs: BytesIO) -> None: end = fs.tell() fs.seek(offset) - if ((end - offset) < WinCertPkcs1.STATIC_STRUCT_SIZE): # size of the static header data + if (end - offset) < WinCertPkcs1.STATIC_STRUCT_SIZE: # size of the static header data raise ValueError("Invalid file stream size") self.Hdr_dwLength = struct.unpack("=I", fs.read(4))[0] @@ -158,10 +158,10 @@ def decode(self, fs: BytesIO) -> None: self.hash_algorithm = uuid.UUID(bytes_le=fs.read(16)) self.cert_data = None - if ((end - fs.tell()) < 1): + if (end - fs.tell()) < 1: raise ValueError("Invalid File stream. No data for signature cert data") - if ((end - fs.tell()) < (self.Hdr_dwLength - WinCertPkcs1.STATIC_STRUCT_SIZE)): + if (end - fs.tell()) < (self.Hdr_dwLength - WinCertPkcs1.STATIC_STRUCT_SIZE): raise ValueError("Invalid file stream size") self.cert_data = memoryview(fs.read(self.Hdr_dwLength - WinCertPkcs1.STATIC_STRUCT_SIZE)) @@ -179,7 +179,7 @@ def PopulateFromFileStream(self, fs: BytesIO) -> None: warn("PopulateFromFileStream is deprecated, use decode instead", DeprecationWarning, 2) return self.decode(fs) - def print(self, out_fs: Optional[BytesIO]=sys.stdout) -> None: + def print(self, out_fs: Optional[BytesIO] = sys.stdout) -> None: """Prints the struct to the console.""" out_fs.write("\n-------------------- WinCertPKCS115 ---------------------\n") out_fs.write(f" Hdr_dwLength: 0x{self.Hdr_dwLength:0X}\n") @@ -190,7 +190,7 @@ def print(self, out_fs: Optional[BytesIO]=sys.stdout) -> None: cdl = self.cert_data.tolist() hexdump(cdl, out_fs=out_fs) - def Print(self, out_fs: Optional[BytesIO]=sys.stdout) -> None: + def Print(self, out_fs: Optional[BytesIO] = sys.stdout) -> None: """Prints the struct to the console.""" warn("Print is deprecated, use print instead", DeprecationWarning, 2) self.print(out_fs) @@ -255,22 +255,22 @@ class WinCertUefiGuid(object): } WIN_CERTIFICATE; """ - _StructFormat = ' 'WinCertUefiGuid': + def __init__(self, in_data: Optional[BytesIO] = None) -> "WinCertUefiGuid": """Inits the object.""" self.Hdr_dwLength = self._StructSize self.Hdr_wRevision = WinCert.REVISION self.Hdr_wCertificateType = WinCert.WIN_CERT_TYPE_EFI_GUID self.cert_type = self._EFI_CERT_TYPE_PKCS7_GUID - self.cert_data = b'' + self.cert_data = b"" if in_data is not None: self.decode(in_data) @@ -339,7 +339,7 @@ def encode(self) -> str: self.Hdr_dwLength, self.Hdr_wRevision, self.Hdr_wCertificateType, - self.cert_type.bytes_le + self.cert_type.bytes_le, ) return win_cert_header + self.cert_data @@ -379,13 +379,14 @@ def decode(self, in_data: BytesIO) -> bytes: (ValueError): Invalid datatype provided """ - if hasattr(in_data, 'seek'): # Filestream like object + if hasattr(in_data, "seek"): # Filestream like object return self._from_filestream(in_data) - elif hasattr(in_data, 'decode'): # Bytes like object + elif hasattr(in_data, "decode"): # Bytes like object return self._from_buffer(in_data) else: raise ValueError( - f"Invalid datatype provided: {type(in_data)}, data may only be of type filestream or bytes") + f"Invalid datatype provided: {type(in_data)}, data may only be of type filestream or bytes" + ) def _from_buffer(self, buffer: BytesIO) -> bytes: """Loads the struct with values from a buffer. @@ -405,8 +406,7 @@ def _from_buffer(self, buffer: BytesIO) -> bytes: if len(buffer) < self._StructSize: raise ValueError (dwLength, wRevision, wCertificateType, cert_type) = struct.unpack( - self._StructFormat, - buffer[0:self._StructSize] + self._StructFormat, buffer[0 : self._StructSize] ) if dwLength < self._StructSize: raise ValueError @@ -420,10 +420,10 @@ def _from_buffer(self, buffer: BytesIO) -> bytes: self.Hdr_wRevision = wRevision self.Hdr_wCertificateType = wCertificateType self.cert_type = uuid.UUID(bytes_le=cert_type) - self.cert_data = buffer[self._StructSize:self.Hdr_dwLength] + self.cert_data = buffer[self._StructSize : self.Hdr_dwLength] # Return the remaining buffer, if any exists. - return buffer[self.Hdr_dwLength:] + return buffer[self.Hdr_dwLength :] def _from_filestream(self, fs: StringIO) -> bytes: """Un-serialized from a filestream. @@ -480,13 +480,14 @@ def add_cert_data(self, in_data: BytesIO) -> None: self.Hdr_dwLength -= len(self.cert_data) # Account for back compat. Behave differently for file streams. - if hasattr(in_data, 'seek'): + if hasattr(in_data, "seek"): self.cert_data = in_data.read() - elif hasattr(in_data, 'decode'): + elif hasattr(in_data, "decode"): self.cert_data = in_data else: raise ValueError( - f"Invalid datatype provided: {type(in_data)}, data may only be of type filestream or bytes") + f"Invalid datatype provided: {type(in_data)}, data may only be of type filestream or bytes" + ) self.Hdr_dwLength = self.Hdr_dwLength + len(self.cert_data) @@ -512,16 +513,16 @@ def GetCertificate(self) -> bytes: warn("GetCertificate is deprecated, use get_certificate instead", DeprecationWarning, 2) return self.get_certificate() - def print(self, outfs: StringIO=sys.stdout) -> None: + def print(self, outfs: StringIO = sys.stdout) -> None: """Prints struct to console.""" self.dump_info(outfs) - def Print(self, outfs: StringIO=sys.stdout) -> None: + def Print(self, outfs: StringIO = sys.stdout) -> None: """Prints struct to console.""" warn("Print() is deprecated, use print() instead.", DeprecationWarning, 2) self.dump_info(outfs) - def dump_info(self, outfs: StringIO=sys.stdout) -> None: + def dump_info(self, outfs: StringIO = sys.stdout) -> None: """Prints struct to a file stream.""" outfs.write("\n-------------------- WIN_CERTIFICATE ---------------------\n") outfs.write(f"WIN_CERTIFICATE.dwLength = {self.Hdr_dwLength:08X}\n") @@ -546,7 +547,7 @@ def dump_info(self, outfs: StringIO=sys.stdout) -> None: except Exception as exc: raise ValueError("Unable to decode cert_data") from exc - def DumpInfo(self, outfs: StringIO=sys.stdout) -> None: + def DumpInfo(self, outfs: StringIO = sys.stdout) -> None: """Prints struct to a file stream.""" warn("DumpInfo is deprecated, use dump_info instead", DeprecationWarning, 2) self.dump_info(outfs) @@ -573,6 +574,7 @@ def __str__(self) -> str: class WinCert(object): """Object for generating a WinCert.""" + STATIC_STRUCT_SIZE = 8 # WIN_CERTIFICATE.wCertificateTypes UEFI Spec defined WIN_CERT_TYPE_NONE = 0x0000 @@ -596,7 +598,7 @@ def factory(fs: BytesIO) -> Union[WinCertUefiGuid, WinCertPkcs1]: (Exception): Invalid fs (Exception): Invalid fs size """ - if (fs is None): + if fs is None: raise Exception("Invalid File stream") # only populate from file stream those parts that are complete in the file stream @@ -605,7 +607,7 @@ def factory(fs: BytesIO) -> Union[WinCertUefiGuid, WinCertPkcs1]: end = fs.tell() fs.seek(offset) - if ((end - offset) < WinCert.STATIC_STRUCT_SIZE): # size of the static header data + if (end - offset) < WinCert.STATIC_STRUCT_SIZE: # size of the static header data raise Exception("Invalid file stream size") # 1 read len # 2 read revision @@ -616,12 +618,13 @@ def factory(fs: BytesIO) -> Union[WinCertUefiGuid, WinCertPkcs1]: fs.seek(offset) - if (Hdr_wCertificateType == WinCert.WIN_CERT_TYPE_EFI_GUID): + if Hdr_wCertificateType == WinCert.WIN_CERT_TYPE_EFI_GUID: return WinCertUefiGuid(fs) - elif (Hdr_wCertificateType == WinCert.WIN_CERT_TYPE_EFI_PKCS115): + elif Hdr_wCertificateType == WinCert.WIN_CERT_TYPE_EFI_PKCS115: return WinCertPkcs1(fs) else: return None + # # this method is a factory # diff --git a/edk2toollib/utility_functions.py b/edk2toollib/utility_functions.py index 04c54fa4..ea7f2afe 100644 --- a/edk2toollib/utility_functions.py +++ b/edk2toollib/utility_functions.py @@ -7,6 +7,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Module containing utility functions to support re-use in python scripts.""" + import datetime import importlib import inspect @@ -39,7 +40,7 @@ class PropagatingThread(threading.Thread): # noqa def run(self): # noqa self.exc = None try: - if hasattr(self, '_Thread__target'): + if hasattr(self, "_Thread__target"): # Thread uses name mangling prior to Python 3. self.ret = self._Thread__target(*self._Thread__args, **self._Thread__kwargs) else: @@ -56,7 +57,7 @@ def join(self, timeout=None): # noqa # http://stackoverflow.com/questions/19423008/logged-subprocess-communicate # TODO make this a private function -def reader(filepath, outstream, stream, logging_level=logging.INFO, encodingErrors='strict'): # noqa +def reader(filepath, outstream, stream, logging_level=logging.INFO, encodingErrors="strict"): # noqa """Helper functions for running commands from the shell in python environment. Don't use directly @@ -66,22 +67,22 @@ def reader(filepath, outstream, stream, logging_level=logging.INFO, encodingErro """ f = None # open file if caller provided path - if (filepath): + if filepath: f = open(filepath, "w") while True: - s = stream.readline().decode(sys.stdout.encoding or 'utf-8', errors=encodingErrors) + s = stream.readline().decode(sys.stdout.encoding or "utf-8", errors=encodingErrors) if not s: break - if (f is not None): + if f is not None: # write to file if caller provided file f.write(s) - if (outstream is not None): + if outstream is not None: # write to stream object if caller provided object outstream.write(s) logging.log(logging_level, s.rstrip()) stream.close() - if (f is not None): + if f is not None: f.close() @@ -91,7 +92,7 @@ def GetHostInfo() -> namedtuple: Returns: (namedTuple[Host(os, arch, bit)]): Host(os=OS Type, arch=System Architecture, bit=Highest Order Bit) """ - Host = namedtuple('Host', 'os arch bit') + Host = namedtuple("Host", "os arch bit") host_info = platform.uname() os = host_info.system processor_info = host_info.machine @@ -129,27 +130,29 @@ def timing(f: Callable) -> Callable: def function_i_want_to_time(): ``` """ + def wrap(*args: Any) -> int: # time1 = time.time() ret = f(*args) time2 = time.time() - logging.debug('{:s} function took {:.3f} ms'.format(f.__name__, (time2 - time1) * 1000.0)) + logging.debug("{:s} function took {:.3f} ms".format(f.__name__, (time2 - time1) * 1000.0)) return ret + return wrap def RunCmd( cmd: str, parameters: str, - capture: bool=True, - workingdir: str=None, - outfile: Optional[str]=None, - outstream: Optional[str]=None, - environ: Optional[dict]=None, - logging_level: int=logging.INFO, - raise_exception_on_nonzero: bool=False, - encodingErrors: str='strict', - close_fds: bool=True + capture: bool = True, + workingdir: str = None, + outfile: Optional[str] = None, + outstream: Optional[str] = None, + environ: Optional[dict] = None, + logging_level: int = logging.INFO, + raise_exception_on_nonzero: bool = False, + encodingErrors: str = "strict", + close_fds: bool = True, ) -> int: """Run a shell command and print the output to the log file. @@ -177,7 +180,7 @@ def RunCmd( Returns: (int): returncode of called cmd """ - cmd = cmd.strip('"\'') + cmd = cmd.strip("\"'") if " " in cmd: cmd = '"' + cmd + '"' if parameters is not None: @@ -188,9 +191,16 @@ def RunCmd( logging.log(logging_level, "------------------------------------------------") logging.log(logging_level, "--------------Cmd Output Starting---------------") logging.log(logging_level, "------------------------------------------------") - c = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - cwd=workingdir, shell=True, env=environ, close_fds=close_fds) - if (capture): + c = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + cwd=workingdir, + shell=True, + env=environ, + close_fds=close_fds, + ) + if capture: thread = PropagatingThread(target=reader, args=(outfile, outstream, c.stdout, logging_level, encodingErrors)) thread.start() c.wait() @@ -216,13 +226,13 @@ def RunCmd( def RunPythonScript( pythonfile: str, params: str, - capture: bool=True, - workingdir: Optional[str]=None, - outfile: Optional[str]=None, - outstream: Optional[str]=None, - environ:Optional[dict]=None, - logging_level: int=logging.INFO, - raise_exception_on_nonzero: bool=False + capture: bool = True, + workingdir: Optional[str] = None, + outfile: Optional[str] = None, + outstream: Optional[str] = None, + environ: Optional[dict] = None, + logging_level: int = logging.INFO, + raise_exception_on_nonzero: bool = False, ) -> int: """Run a python script and print the output to the log file. @@ -244,14 +254,14 @@ def RunPythonScript( (int): returncode of called cmd """ # locate python file on path - pythonfile.strip('"\'') + pythonfile.strip("\"'") if " " in pythonfile: pythonfile = '"' + pythonfile + '"' params.strip() logging.debug("RunPythonScript: {0} {1}".format(pythonfile, params)) - if (os.path.isabs(pythonfile)): + if os.path.isabs(pythonfile): logging.debug("Python Script was given as absolute path: %s" % pythonfile) - elif (os.path.isfile(os.path.join(os.getcwd(), pythonfile))): + elif os.path.isfile(os.path.join(os.getcwd(), pythonfile)): pythonfile = os.path.join(os.getcwd(), pythonfile) logging.debug("Python Script was given as relative path: %s" % pythonfile) else: @@ -263,9 +273,17 @@ def RunPythonScript( logging.debug("Python Script was found on the path: %s" % pythonfile) break params = pythonfile + " " + params - return RunCmd(sys.executable, params, capture=capture, workingdir=workingdir, outfile=outfile, - outstream=outstream, environ=environ, logging_level=logging_level, - raise_exception_on_nonzero=raise_exception_on_nonzero) + return RunCmd( + sys.executable, + params, + capture=capture, + workingdir=workingdir, + outfile=outfile, + outstream=outstream, + environ=environ, + logging_level=logging_level, + raise_exception_on_nonzero=raise_exception_on_nonzero, + ) def DetachedSignWithSignTool( @@ -273,9 +291,9 @@ def DetachedSignWithSignTool( ToSignFilePath: str, SignatureOutputFile: str, PfxFilePath: str, - PfxPass: Optional[str]=None, - Oid: str="1.2.840.113549.1.7.2", - Eku: Optional[str]=None + PfxPass: Optional[str] = None, + Oid: str = "1.2.840.113549.1.7.2", + Eku: Optional[str] = None, ) -> int: """Locally Sign input file using Windows SDK signtool. @@ -299,20 +317,21 @@ def DetachedSignWithSignTool( # Signtool parameters from # https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/secure-boot-key-generation-and-signing-using-hsm--example # noqa: E501 # Search for "Secure Boot Key Generation and Signing Using HSM" - params = 'sign /fd sha256 /p7ce DetachedSignedData /p7co ' + Oid + ' /p7 "' + \ - OutputDir + '" /f "' + PfxFilePath + '"' + params = ( + "sign /fd sha256 /p7ce DetachedSignedData /p7co " + Oid + ' /p7 "' + OutputDir + '" /f "' + PfxFilePath + '"' + ) if Eku is not None: - params += ' /u ' + Eku + params += " /u " + Eku if PfxPass is not None: # add password if set - params = params + ' /p ' + PfxPass + params = params + " /p " + PfxPass params = params + ' /debug /v "' + ToSignFilePath + '" ' ret = RunCmd(SignToolPath, params) - if (ret != 0): + if ret != 0: logging.error("Signtool failed %d" % ret) return ret signedfile = os.path.join(OutputDir, os.path.basename(ToSignFilePath) + ".p7") - if (not os.path.isfile(signedfile)): + if not os.path.isfile(signedfile): raise Exception("Output file doesn't exist %s" % signedfile) shutil.move(signedfile, SignatureOutputFile) @@ -320,10 +339,7 @@ def DetachedSignWithSignTool( def CatalogSignWithSignTool( - SignToolPath: str, - ToSignFilePath: str, - PfxFilePath: str, - PfxPass: Optional[str]=None + SignToolPath: str, ToSignFilePath: str, PfxFilePath: str, PfxPass: Optional[str] = None ) -> int: """Locally sign input file using Windows SDK signtool. @@ -349,10 +365,10 @@ def CatalogSignWithSignTool( params = "sign /a /fd SHA256 /f " + PfxFilePath if PfxPass is not None: # add password if set - params = params + ' /p ' + PfxPass + params = params + " /p " + PfxPass params = params + ' /debug /v "' + ToSignFilePath + '" ' ret = RunCmd(SignToolPath, params, workingdir=OutputDir) - if (ret != 0): + if ret != 0: logging.error("Signtool failed %d" % ret) return ret @@ -363,8 +379,10 @@ def CatalogSignWithSignTool( # https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons def version_compare(version1: str, version2: str) -> bool: """Compare two versions.""" + def normalize(v: str) -> bool: - return [int(x) for x in re.sub(r'(\.0+)*$', '', v).split(".")] + return [int(x) for x in re.sub(r"(\.0+)*$", "", v).split(".")] + (a, b) = (normalize(version1), normalize(version2)) return (a > b) - (a < b) @@ -399,8 +417,7 @@ def locate_class_in_module(Module: Any, DesiredClass: Any) -> Any: # noqa: ANN4 # Pull out the contents of the module that was provided module_contents = dir(Module) # Filter through the Module, we're only looking for classes. - classList = [getattr(Module, obj) for obj in module_contents - if inspect.isclass(getattr(Module, obj))] + classList = [getattr(Module, obj) for obj in module_contents if inspect.isclass(getattr(Module, obj))] for _class in classList: # Classes that the module import show up in this list too so we need @@ -427,8 +444,8 @@ def RemoveTree(dir_path: str, ignore_errors: bool = False) -> None: """ # Allows for finding paths over the 260 character limit, even if the registry key (LongPathsEnabled) # Is not enabled. - if sys.platform.startswith('win'): - dir_path = '\\\\?\\' + os.path.abspath(dir_path) + if sys.platform.startswith("win"): + dir_path = "\\\\?\\" + os.path.abspath(dir_path) def _remove_readonly(func: Callable, path: str, _: any) -> None: """Private function to attempt to change permissions on file/folder being deleted.""" @@ -448,11 +465,11 @@ def _remove_readonly(func: Callable, path: str, _: any) -> None: def PrintByteList( ByteList: bytearray, - IncludeAscii: bool=True, - IncludeOffset: bool=True, - IncludeHexSep: bool=True, - OffsetStart: int=0, - **kwargs: Any # + IncludeAscii: bool = True, + IncludeOffset: bool = True, + IncludeHexSep: bool = True, + OffsetStart: int = 0, + **kwargs: Any, # ) -> None: """Print a byte array as hex and optionally output ascii as well as offset within the buffer.""" outfs = kwargs.get("outfs", sys.stdout) @@ -461,13 +478,12 @@ def PrintByteList( kwargs["include_offset"] = IncludeOffset warn( - "This function is being replaced by hexdump, if you rely on this behavior switch to hexdump", - DeprecationWarning + "This function is being replaced by hexdump, if you rely on this behavior switch to hexdump", DeprecationWarning ) hexdump(ByteList, offset_start=OffsetStart, outfs=outfs, **kwargs) -def hexdump(byte_list: bytearray, offset_start: int=0, outfs: BytesIO=sys.stdout, **kwargs: Any) -> None: # +def hexdump(byte_list: bytearray, offset_start: int = 0, outfs: BytesIO = sys.stdout, **kwargs: Any) -> None: # """Print a byte array as hex and optionally output ascii as well as offset within the buffer. Args: @@ -484,9 +500,9 @@ def hexdump(byte_list: bytearray, offset_start: int=0, outfs: BytesIO=sys.stdout Returns: None """ - include_ascii = kwargs.get('include_ascii', True) - include_offset = kwargs.get('include_offset', True) - include_hex_sep = kwargs.get('include_hex_sep', True) + include_ascii = kwargs.get("include_ascii", True) + include_offset = kwargs.get("include_offset", True) + include_hex_sep = kwargs.get("include_hex_sep", True) ascii_string = "" index = 0 @@ -575,7 +591,7 @@ def export_c_type_array(buffer_fs: BytesIO, variable_name: str, out_fs: StringIO length = end - start # for some reason os.linesep causes twice the amount of desired newlines - newline = '\n' + newline = "\n" if length == 0: raise ValueError("Binary file length was 0") @@ -588,7 +604,7 @@ def export_c_type_array(buffer_fs: BytesIO, variable_name: str, out_fs: StringIO ascii_string = "" i = 0 - byte = '' + byte = "" for i, byte in enumerate(buffer_fs.read()): if i % bytes_per_row == 0: @@ -629,5 +645,4 @@ def export_c_type_array(buffer_fs: BytesIO, variable_name: str, out_fs: StringIO out_fs.write(f"{newline}}};{newline*2}") if length_variable_name: - out_fs.write( - f"{length_data_type} {length_variable_name} = sizeof {variable_name};{newline*2}") + out_fs.write(f"{length_data_type} {length_variable_name} = sizeof {variable_name};{newline*2}") diff --git a/edk2toollib/windows/capsule/cat_generator.py b/edk2toollib/windows/capsule/cat_generator.py index f8cddd30..a0fd7d1b 100644 --- a/edk2toollib/windows/capsule/cat_generator.py +++ b/edk2toollib/windows/capsule/cat_generator.py @@ -10,6 +10,7 @@ Based on a supplied inf file and uses the winsdk and command line tool Inf2Cat.exe """ + import logging import os from typing import Optional @@ -25,20 +26,22 @@ class CatGenerator(object): arch (str): a supported architecture os (str): a supported os """ - SUPPORTED_OS = {'win10': '10', - '10': '10', - '10_au': '10_AU', - '10_rs2': '10_RS2', - '10_rs3': '10_RS3', - '10_rs4': '10_RS4', - 'server10': 'Server10', - 'server2016': 'Server2016', - 'serverrs2': 'ServerRS2', - 'serverrs3': 'ServerRS3', - 'serverrs4': 'ServerRS4' - } - - def __init__(self, arch: str, os: str) -> 'CatGenerator': + + SUPPORTED_OS = { + "win10": "10", + "10": "10", + "10_au": "10_AU", + "10_rs2": "10_RS2", + "10_rs3": "10_RS3", + "10_rs4": "10_RS4", + "server10": "Server10", + "server2016": "Server2016", + "serverrs2": "ServerRS2", + "serverrs3": "ServerRS3", + "serverrs4": "ServerRS4", + } + + def __init__(self, arch: str, os: str) -> "CatGenerator": """Inits a Cat Generator. Args: @@ -63,7 +66,7 @@ def Arch(self, value: str) -> None: value = value.lower() if (value == "x64") or (value == "amd64"): # support amd64 value so INF and CAT tools can use same arch value self._arch = "X64" - elif (value == "arm"): + elif value == "arm": self._arch = "ARM" elif (value == "arm64") or (value == "aarch64"): # support UEFI defined aarch64 value as well self._arch = "ARM64" @@ -84,12 +87,12 @@ def OperatingSystem(self, value: str) -> None: (ValueError): Operating system is unsupported """ key = value.lower() - if (key not in CatGenerator.SUPPORTED_OS.keys()): + if key not in CatGenerator.SUPPORTED_OS.keys(): logging.critical("Unsupported Operating System: %s", key) raise ValueError("Unsupported Operating System") self._operatingsystem = CatGenerator.SUPPORTED_OS[key] - def MakeCat(self, OutputCatFile: str, PathToInf2CatTool: Optional[str]=None) -> int: + def MakeCat(self, OutputCatFile: str, PathToInf2CatTool: Optional[str] = None) -> int: """Generates a cat file to the outputcatfile directory. Args: @@ -102,20 +105,22 @@ def MakeCat(self, OutputCatFile: str, PathToInf2CatTool: Optional[str]=None) -> (Exception): Cat file not found, but tool executed successfully """ # Find Inf2Cat tool - if (PathToInf2CatTool is None): + if PathToInf2CatTool is None: PathToInf2CatTool = FindToolInWinSdk("Inf2Cat.exe") # check if exists if PathToInf2CatTool is None or not os.path.exists(PathToInf2CatTool): - raise Exception("Can't find Inf2Cat on this machine. Please install the Windows 10 WDK - " - "https://developer.microsoft.com/en-us/windows/hardware/windows-driver-kit") + raise Exception( + "Can't find Inf2Cat on this machine. Please install the Windows 10 WDK - " + "https://developer.microsoft.com/en-us/windows/hardware/windows-driver-kit" + ) OutputFolder = os.path.dirname(OutputCatFile) # Make Cat file cmd = "/driver:. /os:" + self.OperatingSystem + "_" + self.Arch + " /verbose /uselocaltime" ret = RunCmd(PathToInf2CatTool, cmd, workingdir=OutputFolder) - if (ret != 0): + if ret != 0: raise Exception("Creating Cat file Failed with errorcode %d" % ret) - if (not os.path.isfile(OutputCatFile)): + if not os.path.isfile(OutputCatFile): raise Exception("CAT file (%s) not created" % OutputCatFile) return 0 diff --git a/edk2toollib/windows/capsule/inf_generator.py b/edk2toollib/windows/capsule/inf_generator.py index 9fb6cc7b..88f625dd 100644 --- a/edk2toollib/windows/capsule/inf_generator.py +++ b/edk2toollib/windows/capsule/inf_generator.py @@ -10,6 +10,7 @@ Uses supplied information such as Name, Version, ESRT Guid, Rollback, etc. """ + import datetime import logging import os @@ -17,11 +18,13 @@ import uuid from typing import Optional -OS_BUILD_VERSION_DIRID13_SUPPORT = '10.0...17134' +OS_BUILD_VERSION_DIRID13_SUPPORT = "10.0...17134" + class InfSection(object): """Object representing an INF Section.""" - def __init__(self, name: str) -> 'InfSection': + + def __init__(self, name: str) -> "InfSection": """Inits the object.""" self.Name = name self.Items = [] @@ -37,6 +40,7 @@ def __str__(self) -> str: class InfGenerator(object): """An object that generates an INF file from data it is initialized with.""" + ### INF Template ### TEMPLATE = r"""; ; {Name}.inf @@ -98,12 +102,7 @@ class InfGenerator(object): HKLM,SYSTEM\CurrentControlSet\Control\FirmwareResources\{{{EsrtGuid}}},Policy,%REG_DWORD%,1 """ - SUPPORTED_ARCH = {'amd64': 'amd64', - 'x64': 'amd64', - 'arm': 'arm', - 'arm64': 'ARM64', - 'aarch64': 'ARM64' - } + SUPPORTED_ARCH = {"amd64": "amd64", "x64": "amd64", "arm": "arm", "arm64": "ARM64", "aarch64": "ARM64"} def __init__( self, @@ -113,7 +112,7 @@ def __init__( arch: str, description_string: str, version_string: str, - version_hex: str + version_hex: str, ) -> None: """Inits the object with data necessary to generate an INF file. @@ -150,7 +149,7 @@ def Name(self, value: str) -> None: (ValueError): Invalid Characters in name """ # test here for invalid chars - if not (re.compile(r'[\w-]*$')).match(value): + if not (re.compile(r"[\w-]*$")).match(value): logging.critical("Name invalid: '%s'", value) raise ValueError("Name has invalid chars.") self._name = value @@ -171,7 +170,7 @@ def Manufacturer(self) -> str: NOTE: Returns Provider attribute if Manufacturer attribute is not set. """ - if (self._manufacturer is None): + if self._manufacturer is None: return self.Provider return self._manufacturer @@ -238,7 +237,7 @@ def VersionHex(self, value: int) -> None: (ValueError): hex does not fit in a 32but uint """ a = int(value, 0) - if (a > 0xFFFFFFFF): + if a > 0xFFFFFFFF: logging.critical("VersionHex invalid: '%s'", value) raise ValueError("VersionHex must fit within 32bit value range for unsigned integer") self._versionhex = a @@ -256,7 +255,7 @@ def Arch(self, value: str) -> None: (ValueError): Unsupported Arch """ key = value.lower() - if (key not in InfGenerator.SUPPORTED_ARCH.keys()): + if key not in InfGenerator.SUPPORTED_ARCH.keys(): logging.critical("Arch invalid: '%s'", value) raise ValueError("Unsupported Architecture") self._arch = InfGenerator.SUPPORTED_ARCH[key] @@ -276,7 +275,7 @@ def Date(self, value: datetime.date) -> None: Raises: (ValueError): not a datetime.date object """ - if (not isinstance(value, datetime.date)): + if not isinstance(value, datetime.date): raise ValueError("Date must be a datetime.date object") self._date = value @@ -293,7 +292,7 @@ def IntegrityFilename(self, value: str) -> None: """Setter for the IntegrityFile name.""" self._integrityfile = value - def MakeInf(self, OutputInfFilePath: os.PathLike, FirmwareBinFileName: str, Rollback: bool=False) -> int: + def MakeInf(self, OutputInfFilePath: os.PathLike, FirmwareBinFileName: str, Rollback: bool = False) -> int: """Generates the INF with provided information. Args: @@ -302,26 +301,27 @@ def MakeInf(self, OutputInfFilePath: os.PathLike, FirmwareBinFileName: str, Roll Rollback (:obj:`bool`, optional): Generate with Rollback template """ RollbackString = "" - if (Rollback): + if Rollback: RollbackString = InfGenerator.ROLLBACKTEMPLATE.format(EsrtGuid=self.EsrtGuid) binfilename = os.path.basename(FirmwareBinFileName) - copy_files = InfSection('Firmware_CopyFiles') + copy_files = InfSection("Firmware_CopyFiles") copy_files.Items.append(binfilename) - add_reg = InfSection('Firmware_AddReg') + add_reg = InfSection("Firmware_AddReg") add_reg.Items.append("HKR,,FirmwareId,,{{{guid}}}".format(guid=self.EsrtGuid)) - add_reg.Items.append("HKR,,FirmwareVersion,%REG_DWORD%,{version}".format( - version=self.VersionHex)) + add_reg.Items.append("HKR,,FirmwareVersion,%REG_DWORD%,{version}".format(version=self.VersionHex)) add_reg.Items.append("HKR,,FirmwareFilename,,%13%\\{file_name}".format(file_name=binfilename)) - disks_files = InfSection('SourceDisksFiles') + disks_files = InfSection("SourceDisksFiles") disks_files.Items.append("{file_name} = 1".format(file_name=binfilename)) if self.IntegrityFilename != "": copy_files.Items.append(self.IntegrityFilename) - add_reg.Items.append("HKR,,FirmwareIntegrityFilename,,%13%\\{file_name}".format(file_name=self.IntegrityFilename)) + add_reg.Items.append( + "HKR,,FirmwareIntegrityFilename,,%13%\\{file_name}".format(file_name=self.IntegrityFilename) + ) disks_files.Items.append("{file_name} = 1".format(file_name=self.IntegrityFilename)) Content = InfGenerator.TEMPLATE.format( @@ -337,7 +337,8 @@ def MakeInf(self, OutputInfFilePath: os.PathLike, FirmwareBinFileName: str, Roll Rollback=RollbackString, FirmwareCopyFilesSection=copy_files, FirmwareAddRegSection=add_reg, - SourceDisksFilesSection=disks_files) + SourceDisksFilesSection=disks_files, + ) with open(OutputInfFilePath, "w") as f: f.write(Content) diff --git a/edk2toollib/windows/capsule/inf_generator2.py b/edk2toollib/windows/capsule/inf_generator2.py index 2e9729b1..2229695d 100644 --- a/edk2toollib/windows/capsule/inf_generator2.py +++ b/edk2toollib/windows/capsule/inf_generator2.py @@ -10,25 +10,31 @@ Supports targeting multiple ESRT nodes with the same INF """ + import re import textwrap import uuid from datetime import datetime from typing import Optional -SUPPORTED_ARCH = {'amd64': 'amd64', - 'x64': 'amd64', - 'arm': 'arm', - 'arm64': 'ARM64', - 'aarch64': 'ARM64' - } +SUPPORTED_ARCH = {"amd64": "amd64", "x64": "amd64", "arm": "arm", "arm64": "ARM64", "aarch64": "ARM64"} + +OS_BUILD_VERSION_DIRID13_SUPPORT = "10.0...17134" -OS_BUILD_VERSION_DIRID13_SUPPORT = '10.0...17134' class InfHeader(object): """The INF header at the start of the INF file.""" - def __init__(self, Name: str, VersionStr: str, CreationDate: str, Arch: str, Provider: str, Manufacturer: str, - InfStrings: 'InfStrings') -> 'InfHeader': + + def __init__( + self, + Name: str, + VersionStr: str, + CreationDate: str, + Arch: str, + Provider: str, + Manufacturer: str, + InfStrings: "InfStrings", + ) -> "InfHeader": """Instantiate an INF header object. Args: @@ -60,7 +66,7 @@ def Name(self, value: str) -> None: (ValueError): Invalid chars in string """ # test here for invalid chars - if not (re.compile(r'[\w-]*$')).match(value): + if not (re.compile(r"[\w-]*$")).match(value): raise ValueError("Name has invalid chars.") self._name = value @@ -100,7 +106,7 @@ def Arch(self) -> str: def Arch(self, value: str) -> str: """Validates the Architecture before setting the attribute.""" key = value.lower() - if (key not in SUPPORTED_ARCH.keys()): + if key not in SUPPORTED_ARCH.keys(): raise ValueError("Unsupported Architecture") self._arch = SUPPORTED_ARCH[key] @@ -130,9 +136,18 @@ def __str__(self) -> str: class InfFirmware(object): """Individual firmware sections within the INF.""" - def __init__(self, Tag: str, Description: str, EsrtGuid: str, VersionInt: str, FirmwareFile: str, - InfStrings: 'InfStrings', InfSourceFiles: 'InfSourceFiles', Rollback: Optional[bool] = False, - IntegrityFile: Optional[str] = None) -> 'InfFirmware': + def __init__( + self, + Tag: str, + Description: str, + EsrtGuid: str, + VersionInt: str, + FirmwareFile: str, + InfStrings: "InfStrings", + InfSourceFiles: "InfSourceFiles", + Rollback: Optional[bool] = False, + IntegrityFile: Optional[str] = None, + ) -> "InfFirmware": """Instantiate an INF firmware object. Args: @@ -158,7 +173,7 @@ def __init__(self, Tag: str, Description: str, EsrtGuid: str, VersionInt: str, F InfSourceFiles.AddFile(FirmwareFile) self.Rollback = Rollback self.IntegrityFile = IntegrityFile - if (self.IntegrityFile is not None): + if self.IntegrityFile is not None: InfSourceFiles.AddFile(IntegrityFile) InfStrings.AddNonLocalizableString("REG_DWORD", "0x00010001") @@ -175,7 +190,7 @@ def Tag(self, value: str) -> None: (ValueError): Invalid character for a tag """ # test here for invalid chars - if not (re.compile(r'[\w-]*$')).match(value): + if not (re.compile(r"[\w-]*$")).match(value): raise ValueError("Tag has invalid chars.") self._tag = value @@ -203,7 +218,7 @@ def VersionInt(self, value: int) -> None: def __str__(self) -> str: """Return the string representation of this InfFirmware object.""" # build rollback string, if required. - if (self.Rollback): + if self.Rollback: RollbackStr = textwrap.dedent(f"""\ AddReg = {self.Tag}_DowngradePolicy_AddReg @@ -214,7 +229,7 @@ def __str__(self) -> str: RollbackStr = "" # build integrity file string, if required. - if (self.IntegrityFile is not None): + if self.IntegrityFile is not None: IntegrityFile = f"{self.IntegrityFile}\n" IntegrityFileReg = f"HKR,,FirmwareIntegrityFilename,,%13%\\{self.IntegrityFile}\n" else: @@ -250,7 +265,8 @@ def __str__(self) -> str: class InfFirmwareSections(object): """A collection of firmware sections and associated common metadata.""" - def __init__(self, Arch: str, InfStrings: 'InfStrings') -> 'InfFirmwareSections': + + def __init__(self, Arch: str, InfStrings: "InfStrings") -> "InfFirmwareSections": """Instantiate an INF firmware sections object. Args: @@ -270,7 +286,7 @@ def Arch(self) -> str: def Arch(self, value: str) -> str: """Validates the Architecture before setting the attribute.""" key = value.lower() - if (key not in SUPPORTED_ARCH.keys()): + if key not in SUPPORTED_ARCH.keys(): raise ValueError("Unsupported Architecture") self._arch = SUPPORTED_ARCH[key] @@ -300,7 +316,8 @@ def __str__(self) -> str: class InfSourceFiles(object): """The collection of source files that are referenced by other sections of the INF.""" - def __init__(self, DiskName: str, InfStrings: 'InfStrings') -> 'InfSourceFiles': + + def __init__(self, DiskName: str, InfStrings: "InfStrings") -> "InfSourceFiles": """Instantiate an INF source files object. Args: @@ -308,8 +325,8 @@ def __init__(self, DiskName: str, InfStrings: 'InfStrings') -> 'InfSourceFiles': InfStrings (InfStrings): An InfStrings object representing the "Strings" section of this INF file. """ self.Files = [] - InfStrings.AddLocalizableString('DiskName', DiskName) - InfStrings.AddNonLocalizableString('DIRID_WINDOWS', "10") + InfStrings.AddLocalizableString("DiskName", DiskName) + InfStrings.AddNonLocalizableString("DIRID_WINDOWS", "10") def AddFile(self, Filename: str) -> None: """Adds a new file to this InfSourceFiles object. @@ -318,15 +335,15 @@ def AddFile(self, Filename: str) -> None: Filename (str): Filename (basename only) of the file to be added. (e.g. "Firmware1234.bin") """ # test here for invalid chars. For filenames, this permits a-z, A-Z, 0-9, _, -, and . characters. - if not (re.compile(r'[\.\w-]*$')).match(Filename): + if not (re.compile(r"[\.\w-]*$")).match(Filename): raise ValueError("Filename has invalid chars.") - if (Filename not in self.Files): + if Filename not in self.Files: self.Files.append(Filename) def __str__(self) -> str: """Return the string representation of this InfSourceFIles object.""" - Files = ''.join("{0} = 1\n".format(file) for file in self.Files) + Files = "".join("{0} = 1\n".format(file) for file in self.Files) outstr = textwrap.dedent("""\ [SourceDisksNames] 1 = %DiskName% @@ -347,7 +364,8 @@ class InfStrings(object): strings can be localizable or non-localizable """ - def __init__(self) -> 'InfStrings': + + def __init__(self) -> "InfStrings": """Instantiate an INF strings object.""" self.LocalizableStrings = {} self.NonLocalizableStrings = {} @@ -363,7 +381,7 @@ def AddLocalizableString(self, Key: str, Value: str) -> None: """ # The inf spec says keys here should be "letters, digits, and/or other explicitly visible characters". # for simplicity, this just enforces that it must be a string that matches \w+ - if not (re.compile(r'\w+$')).match(Key): + if not (re.compile(r"\w+$")).match(Key): raise ValueError("Key has invalid chars.") self.LocalizableStrings[Key] = Value @@ -378,7 +396,7 @@ def AddNonLocalizableString(self, Key: str, Value: str) -> None: """ # The inf spec says keys here should be "letters, digits, and/or other explicitly visible characters". # for simplicity, this just enforces that it must be a string that matches \w+ - if not (re.compile(r'\w+$')).match(Key): + if not (re.compile(r"\w+$")).match(Key): raise ValueError("Key has invalid chars.") self.NonLocalizableStrings[Key] = Value @@ -386,12 +404,12 @@ def __str__(self) -> str: """Return the string representation of this InfStrings object.""" LocalizedStrings = "" LongestKey = max(len(Key) for Key in self.LocalizableStrings.keys()) - for (Key, Value) in self.LocalizableStrings.items(): + for Key, Value in self.LocalizableStrings.items(): LocalizedStrings += '{0:{width}} = "{1}"\n'.format(Key, Value, width=LongestKey) NonLocalizedStrings = "" LongestKey = max(len(Key) for Key in self.NonLocalizableStrings.keys()) - for (Key, Value) in self.NonLocalizableStrings.items(): + for Key, Value in self.NonLocalizableStrings.items(): NonLocalizedStrings += "{0:{width}} = {1}\n".format(Key, Value, width=LongestKey) outstr = textwrap.dedent("""\ @@ -408,8 +426,17 @@ def __str__(self) -> str: class InfFile(object): """An object representing an INF file.""" - def __init__(self, Name: str, VersionStr: str, CreationDate: str, Provider: str, ManufacturerName: str, - Arch: Optional[str] = 'amd64', DiskName: Optional[str] = "Firmware Update") -> 'InfFile': + + def __init__( + self, + Name: str, + VersionStr: str, + CreationDate: str, + Provider: str, + ManufacturerName: str, + Arch: Optional[str] = "amd64", + DiskName: Optional[str] = "Firmware Update", + ) -> "InfFile": """Instantiate an INF file object. This object represents the entire INF file. @@ -431,8 +458,16 @@ def __init__(self, Name: str, VersionStr: str, CreationDate: str, Provider: str, self.InfHeader = InfHeader(Name, VersionStr, CreationDate, Arch, Provider, ManufacturerName, self.InfStrings) self.InfFirmwareSections = InfFirmwareSections(Arch, self.InfStrings) - def AddFirmware(self, Tag: str, Description: str, EsrtGuid: str, VersionInt: str, FirmwareFile: str, - Rollback: Optional[bool] = False, IntegrityFile: Optional[str] = None) -> None: + def AddFirmware( + self, + Tag: str, + Description: str, + EsrtGuid: str, + VersionInt: str, + FirmwareFile: str, + Rollback: Optional[bool] = False, + IntegrityFile: Optional[str] = None, + ) -> None: """Adds a firmware target to the INF. Args: @@ -446,8 +481,17 @@ def AddFirmware(self, Tag: str, Description: str, EsrtGuid: str, VersionInt: str IntegrityFile (:obj:`str`, optional): Filename (basename only) of the integrity file associated with this firmware (e.g. "integrity123.bin"). Optional - if not specified, no integrity file will be included. """ - firmwareSection = InfFirmware(Tag, Description, EsrtGuid, VersionInt, FirmwareFile, - self.InfStrings, self.InfSourceFiles, Rollback, IntegrityFile) + firmwareSection = InfFirmware( + Tag, + Description, + EsrtGuid, + VersionInt, + FirmwareFile, + self.InfStrings, + self.InfSourceFiles, + Rollback, + IntegrityFile, + ) self.InfFirmwareSections.AddSection(firmwareSection) def __str__(self) -> str: diff --git a/edk2toollib/windows/locate_tools.py b/edk2toollib/windows/locate_tools.py index f49ecdea..2382b471 100644 --- a/edk2toollib/windows/locate_tools.py +++ b/edk2toollib/windows/locate_tools.py @@ -20,6 +20,7 @@ NOTE: Has the capability to download VSwhere. """ + import glob import importlib.resources as resources import logging @@ -67,7 +68,7 @@ def _DownloadVsWhere(unpack_folder: os.PathLike = None) -> None: if not os.path.isfile(out_file_name): try: # Download the file and save it locally under `temp_file_name` - with urllib.request.urlopen(__URL) as response, open(out_file_name, 'wb') as out_file: + with urllib.request.urlopen(__URL) as response, open(out_file_name, "wb") as out_file: out_file.write(response.read()) except urllib.error.HTTPError as e: logging.error("We ran into an issue when getting VsWhere") @@ -76,6 +77,7 @@ def _DownloadVsWhere(unpack_folder: os.PathLike = None) -> None: # do the hash to make sure the file is good with open(out_file_name, "rb") as file: import hashlib + temp_file_sha256 = hashlib.sha256(file.read()).hexdigest() if temp_file_sha256 != __SHA256: # delete the file since it's not what we're expecting @@ -143,6 +145,7 @@ def FindWithVsWhere(products: str = "*", vs_version: Optional[str] = None) -> Op results = FindAllWithVsWhere(products, vs_version) return results[0] if results else None + def FindAllWithVsWhere(products: str = "*", vs_version: Optional[str] = None) -> Optional[List[str]]: """Finds a product with VS Where. Returns all matches, sorted by newest version. @@ -163,9 +166,9 @@ def FindAllWithVsWhere(products: str = "*", vs_version: Optional[str] = None) -> if vs_where_path is None: raise EnvironmentError("Unable to locate the VsWhere Executable.") - if (products is not None): + if products is not None: cmd += " -products " + products - if (vs_version is not None): + if vs_version is not None: vs_version = vs_version.lower() if vs_version in supported_vs_versions.keys(): cmd += " -version " + supported_vs_versions[vs_version] @@ -173,12 +176,12 @@ def FindAllWithVsWhere(products: str = "*", vs_version: Optional[str] = None) -> raise ValueError(f"{vs_version} unsupported. Supported Versions: {' '.join(supported_vs_versions)}") a = StringIO() ret = RunCmd(vs_where_path, cmd, outstream=a) - if (ret != 0): + if ret != 0: a.close() raise RuntimeError(f"Unkown Error while executing VsWhere: errcode {ret}.") p1 = a.getvalue().strip() a.close() - if (len(p1.strip()) > 0): + if len(p1.strip()) > 0: return [line.strip() for line in p1.splitlines()] return None @@ -220,10 +223,12 @@ def QueryVcVariables(keys: list, arch: str = None, product: str = None, vs_versi logging.error(err_msg) raise ValueError(err_msg) - if len(os.environ['PATH']) > 8191: - w = "Win32 Command prompt ignores any environment variables longer then 8191 characters, but your path is "\ - f"{len(os.environ['PATH'])} characters. Due to this, PATH will not be used when searching for "\ + if len(os.environ["PATH"]) > 8191: + w = ( + "Win32 Command prompt ignores any environment variables longer then 8191 characters, but your path is " + f"{len(os.environ['PATH'])} characters. Due to this, PATH will not be used when searching for " f"[{interesting}]. This could result in missing keys." + ) logging.warning(w) # Attempt to find vcvarsall.bat from any of the found VS installations @@ -248,17 +253,19 @@ def QueryVcVariables(keys: list, arch: str = None, product: str = None, vs_versi if popen.wait() != 0: stderr = stderr.decode("mbcs") if stderr.startswith("The input line is too long"): - stderr = ".bat cmd can not handle args greater than 8191 chars; your total ENV var len exceeds 8191. "\ - "Reduce the total length of your ENV variables to resolve this (Typically your PATH is "\ - "too long)." + stderr = ( + ".bat cmd can not handle args greater than 8191 chars; your total ENV var len exceeds 8191. " + "Reduce the total length of your ENV variables to resolve this (Typically your PATH is " + "too long)." + ) logging.error(stderr) raise RuntimeError(stderr) stdout = stdout.decode("mbcs") for line in stdout.split("\n"): - if '=' not in line: + if "=" not in line: continue line = line.strip() - key, value = line.split('=', 1) + key, value = line.split("=", 1) if key.upper() in interesting: if value.endswith(os.pathsep): value = value[:-1] @@ -374,7 +381,7 @@ def FindToolInWinSdk(tool: str, product: str = None, arch: str = None) -> str: match_offset = len(sdk_dir) # look for something like 10.0.12323.0123 - windows_ver_regex = re.compile(r'\d+\.\d+\.\d+\.\d+') + windows_ver_regex = re.compile(r"\d+\.\d+\.\d+\.\d+") top_version_so_far = -1 top_match = None # Look at in match in the tree diff --git a/edk2toollib/windows/policy/firmware_policy.py b/edk2toollib/windows/policy/firmware_policy.py index e5db6d18..4f24a978 100644 --- a/edk2toollib/windows/policy/firmware_policy.py +++ b/edk2toollib/windows/policy/firmware_policy.py @@ -85,7 +85,8 @@ class Rule(object): Class for storing, serializing, deserializing, & printing RULE elements """ - StructFormat = ' 'Rule': + OffsetToValue: int = 0, + ) -> "Rule": """Inits the Rule Object. Args: @@ -117,18 +118,20 @@ def __init__( self.ValueName = ValueName self.Value = PolicyValue(Value.valueType, Value.value) - def __eq__(self, other: 'Rule') -> bool: + def __eq__(self, other: "Rule") -> bool: """Rule table offsets are not considered for equivalency, only the actual key/value.""" - if (self.RootKey == other.RootKey + if ( + self.RootKey == other.RootKey and self.SubKeyName == other.SubKeyName and self.ValueName == other.ValueName - and self.Value == other.Value): + and self.Value == other.Value + ): return True else: return False @classmethod - def FromFsAndVtOffset(cls: 'Rule', fs: BinaryIO, vtOffset: int) -> 'Rule': + def FromFsAndVtOffset(cls: "Rule", fs: BinaryIO, vtOffset: int) -> "Rule": """Construct a Rule initialized from a deserialized stream and vtOffset. Args: @@ -139,22 +142,28 @@ def FromFsAndVtOffset(cls: 'Rule', fs: BinaryIO, vtOffset: int) -> 'Rule': (Exception): Invalid File Stream or value table offset """ if fs is None or vtOffset is None: - raise Exception('Invalid File stream or Value Table offset') - (RootKey, OffsetToSubKeyName, - OffsetToValueName, OffsetToValue) = struct.unpack( - cls.StructFormat, fs.read(cls.StructSize)) + raise Exception("Invalid File stream or Value Table offset") + (RootKey, OffsetToSubKeyName, OffsetToValueName, OffsetToValue) = struct.unpack( + cls.StructFormat, fs.read(cls.StructSize) + ) orig_offset = fs.tell() SubKeyName = PolicyString.FromFileStream(fs=fs, fsOffset=vtOffset + OffsetToSubKeyName) ValueName = PolicyString.FromFileStream(fs=fs, fsOffset=vtOffset + OffsetToValueName) Value = PolicyValue.FromFileStream(fs=fs, fsOffset=vtOffset + OffsetToValue) fs.seek(orig_offset) - return cls(RootKey=RootKey, OffsetToSubKeyName=OffsetToSubKeyName, - OffsetToValueName=OffsetToValueName, OffsetToValue=OffsetToValue, - SubKeyName=SubKeyName, ValueName=ValueName, Value=Value) + return cls( + RootKey=RootKey, + OffsetToSubKeyName=OffsetToSubKeyName, + OffsetToValueName=OffsetToValueName, + OffsetToValue=OffsetToValue, + SubKeyName=SubKeyName, + ValueName=ValueName, + Value=Value, + ) @classmethod - def FromFsAndVtBytes(cls: 'Rule', fs: BinaryIO, vt: bytes) -> 'Rule': + def FromFsAndVtBytes(cls: "Rule", fs: BinaryIO, vt: bytes) -> "Rule": """Contstruct a Rule initialized from a deserialized stream and value table. Args: @@ -165,31 +174,37 @@ def FromFsAndVtBytes(cls: 'Rule', fs: BinaryIO, vt: bytes) -> 'Rule': (Exception): Invalid File Stream or value table """ if fs is None or vt is None: - raise Exception('Invalid File stream or Value Table offset') - (RootKey, OffsetToSubKeyName, - OffsetToValueName, OffsetToValue) = struct.unpack( - cls.StructFormat, fs.read(cls.StructSize)) + raise Exception("Invalid File stream or Value Table offset") + (RootKey, OffsetToSubKeyName, OffsetToValueName, OffsetToValue) = struct.unpack( + cls.StructFormat, fs.read(cls.StructSize) + ) SubKeyName = PolicyString.FromBytes(vt, OffsetToSubKeyName) ValueName = PolicyString.FromBytes(vt, OffsetToValueName) Value = PolicyValue.FromBytes(vt, OffsetToValue) - return cls(RootKey=RootKey, OffsetToSubKeyName=OffsetToSubKeyName, - OffsetToValueName=OffsetToValueName, OffsetToValue=OffsetToValue, - SubKeyName=SubKeyName, ValueName=ValueName, Value=Value) - - def Print(self, prefix: str = '') -> None: + return cls( + RootKey=RootKey, + OffsetToSubKeyName=OffsetToSubKeyName, + OffsetToValueName=OffsetToValueName, + OffsetToValue=OffsetToValue, + SubKeyName=SubKeyName, + ValueName=ValueName, + Value=Value, + ) + + def Print(self, prefix: str = "") -> None: """Prints the contents of the Rule. Args: prefix (:obj:`str`, optional): Prefix to put in front of print statement. """ - print('%sRule' % (prefix,)) - print('%s RootKey: %x' % (prefix, self.RootKey)) - print('%s SubKeyNameOffset: %x' % (prefix, self.OffsetToSubKeyName)) - print('%s ValueNameOffset: %x' % (prefix, self.OffsetToValueName)) - print('%s ValueOffset: %x' % (prefix, self.OffsetToValue)) - self.SubKeyName.Print(prefix=prefix + ' SubKeyName ') - self.ValueName.Print(prefix=prefix + ' ValueName ') - self.Value.Print(prefix=prefix + ' ') + print("%sRule" % (prefix,)) + print("%s RootKey: %x" % (prefix, self.RootKey)) + print("%s SubKeyNameOffset: %x" % (prefix, self.OffsetToSubKeyName)) + print("%s ValueNameOffset: %x" % (prefix, self.OffsetToValueName)) + print("%s ValueOffset: %x" % (prefix, self.OffsetToValue)) + self.SubKeyName.Print(prefix=prefix + " SubKeyName ") + self.ValueName.Print(prefix=prefix + " ValueName ") + self.Value.Print(prefix=prefix + " ") def Serialize(self, ruleOut: bytearray, valueOut: bytearray, offsetInVT: int) -> None: """Serialize Rule. @@ -214,16 +229,18 @@ def Serialize(self, ruleOut: bytearray, valueOut: bytearray, offsetInVT: int) -> self.Value.Serialize(valueOut=localArray) valueOut += localArray - ruleOut += struct.pack(self.StructFormat, self.RootKey, self.OffsetToSubKeyName, - self.OffsetToValueName, self.OffsetToValue) + ruleOut += struct.pack( + self.StructFormat, self.RootKey, self.OffsetToSubKeyName, self.OffsetToValueName, self.OffsetToValue + ) -class PolicyValueType(): +class PolicyValueType: """Class for managing PolicyValueTypes. Class for storing, serializing, deserializing, & printing PolicyValue Types """ - StructFormat = ' 'PolicyValueType': + def __init__(self, Type: int) -> "PolicyValueType": """Inits the PolicyValueType. Args: @@ -253,7 +268,7 @@ def __init__(self, Type: int) -> 'PolicyValueType': """ if Type not in self.SupportedValueTypes: - ErrorMessage = ('Unsupported ValueType: %x' % Type) + ErrorMessage = "Unsupported ValueType: %x" % Type print(ErrorMessage) if STRICT: raise Exception(ErrorMessage) @@ -261,7 +276,7 @@ def __init__(self, Type: int) -> 'PolicyValueType': self.vt = Type @classmethod - def FromFileStream(cls: 'PolicyValueType', fs: BinaryIO, fsOffset: int = None) -> 'PolicyValueType': + def FromFileStream(cls: "PolicyValueType", fs: BinaryIO, fsOffset: int = None) -> "PolicyValueType": """Load a Policy Value Type from a file stream. NOTE: if fsOffset is not specified, stream fs position is at beginning of struct. @@ -276,7 +291,7 @@ def FromFileStream(cls: 'PolicyValueType', fs: BinaryIO, fsOffset: int = None) - return cls(valueType) @classmethod - def FromBytes(cls: 'PolicyValueType', b: bytes, bOffset: int = 0) -> 'PolicyValueType': + def FromBytes(cls: "PolicyValueType", b: bytes, bOffset: int = 0) -> "PolicyValueType": """Inits a PolicyStringValue from a filestream. Args: @@ -286,13 +301,13 @@ def FromBytes(cls: 'PolicyValueType', b: bytes, bOffset: int = 0) -> 'PolicyValu valueType = struct.unpack_from(cls.StructFormat, b, bOffset)[0] return cls(valueType) - def Print(self, prefix: str = '') -> None: + def Print(self, prefix: str = "") -> None: """Prints the contents of the Policy String Type. Args: prefix (:obj:`str`, optional): Prefix to put in front of print statement. """ - print('%s%s%s' % (prefix, 'ValueType: ', self.vt)) + print("%s%s%s" % (prefix, "ValueType: ", self.vt)) def Serialize(self, valueOut: bytearray) -> None: """Serialize the Policy String Type. @@ -302,12 +317,12 @@ def Serialize(self, valueOut: bytearray) -> None: """ valueOut += struct.pack(self.StructFormat, self.vt) - def Get(self: 'PolicyValueType') -> int: + def Get(self: "PolicyValueType") -> int: """Returns the value type.""" return self.vt -class PolicyString(): +class PolicyString: r"""Class for managing PolicyString structures. Class for storing, serializing, deserializing, & printing PolicyString Types @@ -323,10 +338,11 @@ class PolicyString(): The trailing \x00 is not a NULL, it is UTF-16LE encoding of "D" """ - StringLengthFormat = ' 'PolicyString': + def __init__(self, String: str = None) -> "PolicyString": """Inits PolicyStructure. Args: @@ -335,11 +351,11 @@ def __init__(self, String: str = None) -> 'PolicyString': if String: self.String = String else: - self.String = '' + self.String = "" return @classmethod - def FromFileStream(cls: 'PolicyString', fs: BinaryIO, fsOffset: int = None) -> 'PolicyString': + def FromFileStream(cls: "PolicyString", fs: BinaryIO, fsOffset: int = None) -> "PolicyString": """Inits a PolicyString from a file stream. Args: @@ -352,14 +368,13 @@ def FromFileStream(cls: 'PolicyString', fs: BinaryIO, fsOffset: int = None) -> ' if fsOffset: fs.seek(fsOffset) StringLength = struct.unpack(cls.StringLengthFormat, fs.read(cls.StringLengthSize))[0] - LocalString = bytes.decode( - fs.read(StringLength), encoding='utf_16_le') - if (len(LocalString) != (StringLength / 2)): - raise Exception('String length mismatch') + LocalString = bytes.decode(fs.read(StringLength), encoding="utf_16_le") + if len(LocalString) != (StringLength / 2): + raise Exception("String length mismatch") return cls(String=LocalString) @classmethod - def FromBytes(cls: 'PolicyString', b: bytes, bOffset: int = 0) -> 'PolicyString': + def FromBytes(cls: "PolicyString", b: bytes, bOffset: int = 0) -> "PolicyString": """Inits a PolicyString from a filestream. Args: @@ -371,19 +386,18 @@ def FromBytes(cls: 'PolicyString', b: bytes, bOffset: int = 0) -> 'PolicyString' """ StringLength = struct.unpack_from(cls.StringLengthFormat, b, bOffset)[0] bOffset += struct.calcsize(cls.StringLengthFormat) - LocalString = bytes.decode( - b[bOffset: bOffset + StringLength], encoding='utf_16_le') - if (len(LocalString) != (StringLength / 2)): - raise Exception('String length mismatch') + LocalString = bytes.decode(b[bOffset : bOffset + StringLength], encoding="utf_16_le") + if len(LocalString) != (StringLength / 2): + raise Exception("String length mismatch") return cls(String=LocalString) - def Print(self, prefix: str = '') -> None: + def Print(self, prefix: str = "") -> None: """Prints the contents of the Policy String. Args: prefix (:obj:`str`, optional): Prefix to put in front of print statement. """ - print('%s%s%s' % (prefix, 'String: ', self.String)) + print("%s%s%s" % (prefix, "String: ", self.String)) def Serialize(self, valueOut: bytearray) -> None: """Serialize the Policy String. @@ -391,12 +405,12 @@ def Serialize(self, valueOut: bytearray) -> None: Args: valueOut (bytearray): serialized object """ - b = str.encode(self.String, encoding='utf_16_le') + b = str.encode(self.String, encoding="utf_16_le") size = struct.pack(self.StringLengthFormat, len(b)) valueOut += size + b -class PolicyValue(): +class PolicyValue: """Class for managing PolicyValue structures. Class for storing, serializing, deserializing, & printing policy values @@ -407,7 +421,8 @@ class PolicyValue(): valueType (PolicyValueType): Policy Value Type value (struct): Policy String, dword, qword """ - def __init__(self, valueType: PolicyValueType, value: str) -> 'PolicyValue': + + def __init__(self, valueType: PolicyValueType, value: str) -> "PolicyValue": """Inits a Policy Value. Args: @@ -418,7 +433,7 @@ def __init__(self, valueType: PolicyValueType, value: str) -> 'PolicyValue': self.value = value @classmethod - def FromFileStream(cls: 'PolicyValue', fs: BinaryIO, fsOffset: int = None) -> 'PolicyValue': + def FromFileStream(cls: "PolicyValue", fs: BinaryIO, fsOffset: int = None) -> "PolicyValue": """Load a Policy Value from a file stream. NOTE: if fsOffset is not specified, stream fs position is at beginning of struct. @@ -439,17 +454,17 @@ def FromFileStream(cls: 'PolicyValue', fs: BinaryIO, fsOffset: int = None) -> 'P if valueType.Get() is PolicyValueType.POLICY_VALUE_TYPE_STRING: value = PolicyString.FromFileStream(fs=fs) elif valueType.Get() is PolicyValueType.POLICY_VALUE_TYPE_DWORD: - value = struct.unpack(' 'PolicyValue': + def FromBytes(cls: "PolicyValue", b: bytes, bOffset: int = 0) -> "PolicyValue": """Load a Policy Value from bytes. Args: @@ -462,11 +477,11 @@ def FromBytes(cls: 'PolicyValue', b: bytes, bOffset: int = 0) -> 'PolicyValue': if valueType.Get() is PolicyValueType.POLICY_VALUE_TYPE_STRING: value = PolicyString.FromBytes(b, bOffset) elif valueType.Get() is PolicyValueType.POLICY_VALUE_TYPE_DWORD: - value = struct.unpack_from(' str: """Returns the value type.""" return self.valueType - def Print(self, prefix: str = '') -> None: + def Print(self, prefix: str = "") -> None: """Prints the contents of the object. Args: @@ -484,11 +499,11 @@ def Print(self, prefix: str = '') -> None: """ self.valueType.Print(prefix=prefix) if isinstance(self.value, int): - print('%s%s0x%x' % (prefix, 'Value: ', self.value)) - elif (self.valueType.vt == PolicyValueType.POLICY_VALUE_TYPE_STRING): - self.value.Print(prefix + 'Value: ') + print("%s%s0x%x" % (prefix, "Value: ", self.value)) + elif self.valueType.vt == PolicyValueType.POLICY_VALUE_TYPE_STRING: + self.value.Print(prefix + "Value: ") else: - print('%s%s"%s"' % (prefix, 'Value: ', str(self.value))) + print('%s%s"%s"' % (prefix, "Value: ", str(self.value))) def Serialize(self, valueOut: bytearray) -> None: """Serializes the object to valueOut. @@ -505,15 +520,15 @@ def Serialize(self, valueOut: bytearray) -> None: if vt is PolicyValueType.POLICY_VALUE_TYPE_STRING: self.value.Serialize(valueOut) """ NOTE: add a NULL here for consistency with server-side code """ - valueOut += struct.pack(' 'Reserved2': + def __init__(self, fs: BinaryIO = None, vtOffset: int = 0) -> "Reserved2": """Initializes the Reserved2 structure. Args: @@ -540,8 +556,8 @@ def __init__(self, fs: BinaryIO = None, vtOffset: int = 0) -> 'Reserved2': else: self.PopulateFromFileStream(fs, vtOffset) - errorMessage = 'Reserved2 not fully supported' - if (STRICT is True): + errorMessage = "Reserved2 not fully supported" + if STRICT is True: raise Exception(errorMessage) def PopulateFromFileStream(self, fs: BinaryIO, vtOffset: int = 0) -> None: @@ -556,25 +572,24 @@ def PopulateFromFileStream(self, fs: BinaryIO, vtOffset: int = 0) -> None: (Exception): if STRICT is True, cannot deserialize reserved2 values """ if fs is None: - raise Exception('Invalid File stream') - (self.ObjectType, self.Element, self.OffsetToValue) = struct.unpack( - self.StructFormat, fs.read(self.StructSize)) + raise Exception("Invalid File stream") + (self.ObjectType, self.Element, self.OffsetToValue) = struct.unpack(self.StructFormat, fs.read(self.StructSize)) - errorMessage = 'Reserved2 PopulateFromFileStream does not deserialize Reserved2 values' + errorMessage = "Reserved2 PopulateFromFileStream does not deserialize Reserved2 values" print(errorMessage) - if (STRICT is True): + if STRICT is True: raise Exception(errorMessage) - def Print(self, prefix: str = '') -> None: + def Print(self, prefix: str = "") -> None: """Prints the Reserved2 structure. Args: prefix (str): prefix to append when printing to terminal """ - print('%sReserved2' % prefix) - print('%s ObjectType: %x' % (prefix, self.ObjectType)) - print('%s Element: %x' % (prefix, self.Element)) - print('%s ValueOffset: %x' % (prefix, self.OffsetToValue)) + print("%sReserved2" % prefix) + print("%s ObjectType: %x" % (prefix, self.ObjectType)) + print("%s Element: %x" % (prefix, self.Element)) + print("%s ValueOffset: %x" % (prefix, self.OffsetToValue)) def Serialize(self, ruleOut: bytearray, valueOut: bytearray = None, offsetInVT: int = 0) -> None: """Serialize Reserved2 rule. @@ -588,9 +603,9 @@ def Serialize(self, ruleOut: bytearray, valueOut: bytearray = None, offsetInVT: (Exception): if STRICT is True, value serialization not supported """ ruleOut += struct.pack(self.StructFormat, self.ObjectType, self.Element, self.OffsetToValue) - errorMessage = 'Reserved2 value serialization not supported' + errorMessage = "Reserved2 value serialization not supported" print(errorMessage) - if (STRICT is True): + if STRICT is True: raise Exception(errorMessage) @@ -602,17 +617,18 @@ class FirmwarePolicy(object): Typically handles primitive types itself, or delegates to other classes for non-primitive structures, e.g. Rule, PolicyValue, PolicyString """ - FixedStructFormat = ' 'FirmwarePolicy': + def __init__(self, fs: BinaryIO = None) -> "FirmwarePolicy": """Initializes a Firmware Policy object. Args: @@ -672,7 +686,7 @@ def AddRule(self, regRule: Rule) -> bool: (bool): True if added, False if it already existed. """ for rule in self.Rules: - if (rule == regRule): + if rule == regRule: return False self.Rules.append(regRule) self.RulesCount += 1 @@ -690,9 +704,7 @@ def SetDevicePolicy(self, policy: int) -> None: SubKeyName = PolicyString(String=self.FW_POLICY_SUB_KEY_NAME) ValueName = PolicyString(String=self.FW_POLICY_VALUE_NAME) Value = PolicyValue(valueType=policyVT, value=policy) - rule = Rule(RootKey=self.FW_POLICY_ROOT_KEY, - SubKeyName=SubKeyName, - ValueName=ValueName, Value=Value) + rule = Rule(RootKey=self.FW_POLICY_ROOT_KEY, SubKeyName=SubKeyName, ValueName=ValueName, Value=Value) self.AddRule(rule) def SetDeviceTarget(self, target: dict) -> None: @@ -709,9 +721,12 @@ def SetDeviceTarget(self, target: dict) -> None: else: policyVT = PolicyValueType(Type=PolicyValueType.POLICY_VALUE_TYPE_STRING) Value = PolicyValue(valueType=policyVT, value=PolicyString(String=v)) - rule = Rule(RootKey=self.FW_POLICY_ROOT_KEY, - SubKeyName=PolicyString(String=self.FW_POLICY_SUB_KEY_NAME_TARGET), - ValueName=ValueName, Value=Value) + rule = Rule( + RootKey=self.FW_POLICY_ROOT_KEY, + SubKeyName=PolicyString(String=self.FW_POLICY_SUB_KEY_NAME_TARGET), + ValueName=ValueName, + Value=Value, + ) self.AddRule(rule) def SerializeToStream(self, stream: BinaryIO) -> None: @@ -730,16 +745,22 @@ def Serialize(self, output: bytearray) -> None: Args: output (bytearray): bytearray to write to. """ - if (self.Reserved1Count > 0): - ErrorMessage = 'Reserved1 not supported' - if (STRICT is True): + if self.Reserved1Count > 0: + ErrorMessage = "Reserved1 not supported" + if STRICT is True: raise Exception(ErrorMessage) print(ErrorMessage) - fixedSizeHeader = struct.pack(self.FixedStructFormat, - self.FormatVersion, self.PolicyVersion, self.PolicyPublisher.bytes_le, - self.Reserved1Count, self.OptionFlags, - self.Reserved2Count, self.RulesCount) + fixedSizeHeader = struct.pack( + self.FixedStructFormat, + self.FormatVersion, + self.PolicyVersion, + self.PolicyPublisher.bytes_le, + self.Reserved1Count, + self.OptionFlags, + self.Reserved2Count, + self.RulesCount, + ) Reserved2Offset = len(fixedSizeHeader) Reserved2Size = self.Reserved2Count * Reserved2.StructSize @@ -789,7 +810,7 @@ def FromFileStream(self, fs: BinaryIO, parseByBytes: bool = True) -> None: (Exception): an invalid file stream was provided. """ if fs is None: - raise Exception('Invalid File stream') + raise Exception("Invalid File stream") self.parseValueTableViaBytes = parseByBytes @@ -799,44 +820,41 @@ def FromFileStream(self, fs: BinaryIO, parseByBytes: bool = True) -> None: fs.seek(begin) size = end - begin - if (size < self.POLICY_BLOB_MIN_SIZE): - raise Exception('Policy is too small') + if size < self.POLICY_BLOB_MIN_SIZE: + raise Exception("Policy is too small") - self.FormatVersion = struct.unpack(' self.POLICY_FORMAT_VERSION): - print("Policy Format Version %x is not supported" % - self.FormatVersion) - raise Exception('Policy Format Version is newer than supported') + self.FormatVersion = struct.unpack(" self.POLICY_FORMAT_VERSION: + print("Policy Format Version %x is not supported" % self.FormatVersion) + raise Exception("Policy Format Version is newer than supported") - self.PolicyVersion = struct.unpack(' 0)): - raise Exception('Reserved1 not supported') + self.Reserved1Count = struct.unpack(" 0): + raise Exception("Reserved1 not supported") self.Reserved1 = [] for i in range(self.Reserved1Count): - Reserved1 = struct.unpack( - '<16s', fs.read(struct.calcsize('<16s')))[0] + Reserved1 = struct.unpack("<16s", fs.read(struct.calcsize("<16s")))[0] self.Reserved1.append(uuid.UUID(bytes_le=Reserved1)) - self.OptionFlags = struct.unpack(' end): - raise Exception('Reserved2 larger than buffer') + if (Reserved2Offset + Reserved2Size) > end: + raise Exception("Reserved2 larger than buffer") RulesOffset = Reserved2Offset + Reserved2Size RulesSize = self.RulesCount * Rule.StructSize - if ((RulesOffset + RulesSize) > end): - raise Exception('Rules larger than buffer') + if (RulesOffset + RulesSize) > end: + raise Exception("Rules larger than buffer") self.ValueTableOffset = RulesOffset + RulesSize self.ValueTableSize = end - self.ValueTableOffset @@ -849,8 +867,7 @@ def FromFileStream(self, fs: BinaryIO, parseByBytes: bool = True) -> None: # resume parsing the variable length structures using table offset self.Reserved2 = [] for i in range(self.Reserved2Count): - self.Reserved2.append( - Reserved2(fs=fs, vtOffset=self.ValueTableOffset)) + self.Reserved2.append(Reserved2(fs=fs, vtOffset=self.ValueTableOffset)) self.Rules = [] for i in range(self.RulesCount): @@ -860,37 +877,39 @@ def FromFileStream(self, fs: BinaryIO, parseByBytes: bool = True) -> None: RegRule = Rule.FromFsAndVtOffset(fs=fs, vtOffset=self.ValueTableOffset) self.Rules.append(RegRule) - def PrintDevicePolicy(self, devicePolicy: int, prefix: str = '') -> None: + def PrintDevicePolicy(self, devicePolicy: int, prefix: str = "") -> None: """Prints the device policy.""" - prefix = prefix + ' ' + prefix = prefix + " " for bit in self.FW_POLICY_VALUE_ACTION_STRINGS.keys(): if (devicePolicy & bit) != 0: print(prefix + self.FW_POLICY_VALUE_ACTION_STRINGS[bit]) def Print(self) -> None: """Prints the firmware policy structure.""" - prefix = ' ' - print('Firmware Policy') - print(' FormatVersion: %x' % self.FormatVersion) - print(' PolicyVersion: %x' % self.PolicyVersion) - print(' PolicyPublisher: %s' % self.PolicyPublisher) - print(' Reserved1Count: %x' % self.Reserved1Count) + prefix = " " + print("Firmware Policy") + print(" FormatVersion: %x" % self.FormatVersion) + print(" PolicyVersion: %x" % self.PolicyVersion) + print(" PolicyPublisher: %s" % self.PolicyPublisher) + print(" Reserved1Count: %x" % self.Reserved1Count) for item in self.Reserved1: - print(' Reserved1: %s' % item) - print(' OptionFlags: %x' % self.OptionFlags) - print(' Reserved2Count: %x' % self.Reserved2Count) - print(' RulesCount: %x' % self.RulesCount) - print(' ValueTableSize: %x' % self.ValueTableSize) - print(' ValueTableOffset: %x' % self.ValueTableOffset) + print(" Reserved1: %s" % item) + print(" OptionFlags: %x" % self.OptionFlags) + print(" Reserved2Count: %x" % self.Reserved2Count) + print(" RulesCount: %x" % self.RulesCount) + print(" ValueTableSize: %x" % self.ValueTableSize) + print(" ValueTableOffset: %x" % self.ValueTableOffset) for rule in self.Reserved2: rule.Print(prefix=prefix) for rule in self.Rules: rule.Print(prefix=prefix) - if (rule.RootKey == self.FW_POLICY_ROOT_KEY + if ( + rule.RootKey == self.FW_POLICY_ROOT_KEY and rule.SubKeyName.String == self.FW_POLICY_SUB_KEY_NAME - and rule.ValueName.String == self.FW_POLICY_VALUE_NAME): - print(prefix + ' Device Policy:') + and rule.ValueName.String == self.FW_POLICY_VALUE_NAME + ): + print(prefix + " Device Policy:") self.PrintDevicePolicy(devicePolicy=rule.Value.value, prefix=prefix) - print(' Valuetable') + print(" Valuetable") print(self.ValueTable) return diff --git a/tests.unit/database/common.py b/tests.unit/database/common.py index 47e16077..efe6a5aa 100644 --- a/tests.unit/database/common.py +++ b/tests.unit/database/common.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Common functionality to test the tables.""" + import uuid from pathlib import Path @@ -18,7 +19,8 @@ def write_file(file, contents): file.write_text(contents) assert file.read_text() == contents -def make_edk2_cfg_file(*args, **kwargs)->str: + +def make_edk2_cfg_file(*args, **kwargs) -> str: """Returns a string representing the INF generated. Examples: @@ -45,10 +47,11 @@ def make_edk2_cfg_file(*args, **kwargs)->str: out += f"[{key.capitalize()}]\n" for value in values: # value = value.replace("-", " ") - out += f' {value}\n' + out += f" {value}\n" return out + def create_fdf_file(file_path, **kwargs): """Makes a FDF with default values that can be overwritten via kwargs.""" # Make default values. @@ -76,6 +79,7 @@ def create_fdf_file(file_path, **kwargs): write_file(file_path, out) return k + def create_dsc_file(file_path, **kwargs): """Makes a DSC with default values that can be overwritten via kwargs.""" # Make default values. @@ -90,7 +94,7 @@ def create_dsc_file(file_path, **kwargs): "components": kwargs.pop("components", comps), } - for key,value in kwargs.items(): + for key, value in kwargs.items(): k[key] = value # Write to the specified file and return the dict of set values For comparing @@ -98,6 +102,7 @@ def create_dsc_file(file_path, **kwargs): write_file(file_path, out) return k + def create_inf_file(file_path, **kwargs): """Makes an INF with default values that can be overwritten via kwargs.""" # Ensure that these sections are always defined, even if empty @@ -121,8 +126,10 @@ def create_inf_file(file_path, **kwargs): write_file(file_path, out) return k + class Tree: """An empty EDK2 Workspace containing a simple package.""" + def __init__(self, ws: Path): """Initializes the empty tree with a package, driver, and library folder.""" self.ws = ws @@ -145,7 +152,7 @@ def __init__(self, ws: Path): def create_library(self, name: str, lib_cls: str, **kwargs): """Creates a Library INF in the empty tree.""" - path = self.library_folder / f'{name}.inf' + path = self.library_folder / f"{name}.inf" default = { "FILE_GUID": str(uuid.uuid4()), "MODULE_TYPE": "BASE", @@ -159,7 +166,7 @@ def create_library(self, name: str, lib_cls: str, **kwargs): def create_component(self, name: str, module_type: str, **kwargs): """Creates a Component INF in the empty tree.""" - path = self.component_folder / f'{name}.inf' + path = self.component_folder / f"{name}.inf" kwargs["defines"] = { "FILE_GUID": str(uuid.uuid4()), "MODULE_TYPE": module_type, @@ -171,20 +178,17 @@ def create_component(self, name: str, module_type: str, **kwargs): def create_dsc(self, **kwargs): """Creates a dsc in the empty tree.""" - path = self.package / 'TestPkg.dsc' + path = self.package / "TestPkg.dsc" create_dsc_file(path, **kwargs) return str(path.relative_to(self.ws)) def create_fdf(self, **kwargs): """Creates an FDF in the Empty Tree.""" - path = self.package / 'TestPkg.fdf' + path = self.package / "TestPkg.fdf" create_fdf_file(path, **kwargs) return str(path.relative_to(self.ws)) - - - @pytest.fixture def empty_tree(tmp_path): """A Fixture that returns an Tree object.""" diff --git a/tests.unit/database/test_edk2_db.py b/tests.unit/database/test_edk2_db.py index 06096a6c..dbcb8f96 100644 --- a/tests.unit/database/test_edk2_db.py +++ b/tests.unit/database/test_edk2_db.py @@ -24,7 +24,7 @@ def test_load_existing_db(empty_tree: Tree): assert db_path.exists() is False db = Edk2DB(db_path, pathobj=edk2path) - db.register(InfTable(n_jobs = 1)) + db.register(InfTable(n_jobs=1)) db.parse({}) with db.session() as session: rows = session.query(Inf).all() @@ -38,6 +38,7 @@ def test_load_existing_db(empty_tree: Tree): rows = session.query(Inf).all() assert len(rows) == 1 + def test_catch_bad_parser_and_query(empty_tree: Tree): """Test that a bad parser will be caught and logged.""" edk2path = Edk2Path(str(empty_tree.ws), []) @@ -55,6 +56,7 @@ def test_catch_bad_parser_and_query(empty_tree: Tree): with pytest.raises(NotImplementedError): parser.parse(db.session(), db.pathobj, 0, {}) + def test_clear_parsers(empty_tree: Tree): """Test that we can clear all parsers. EnvironmentTable should always persist.""" edk2path = Edk2Path(str(empty_tree.ws), []) @@ -65,6 +67,7 @@ def test_clear_parsers(empty_tree: Tree): db.clear_parsers() assert len(db._parsers) == 0 + def test_multiple_databases_do_not_interfere(empty_tree: Tree): empty_tree.create_library("TestLib1", "TestCls") edk2path = Edk2Path(str(empty_tree.ws), []) @@ -81,7 +84,7 @@ def test_multiple_databases_do_not_interfere(empty_tree: Tree): assert db_path1.exists() assert db_path2.exists() - db1.register(InfTable(n_jobs = 1)) + db1.register(InfTable(n_jobs=1)) db1.parse({}) with db1.session() as session: diff --git a/tests.unit/database/test_environment_table.py b/tests.unit/database/test_environment_table.py index 3186be02..f4c3a7df 100644 --- a/tests.unit/database/test_environment_table.py +++ b/tests.unit/database/test_environment_table.py @@ -48,7 +48,7 @@ def test_environment_with_vars(tmp_path): rows = session.query(Environment).all() assert len(rows) == 1 entry = rows[0] - assert entry.version == 'UNKNOWN' + assert entry.version == "UNKNOWN" assert entry.date.date() == date.today() assert len(entry.values) == 4 diff --git a/tests.unit/database/test_inf_table.py b/tests.unit/database/test_inf_table.py index f69ad4ff..49895ed7 100644 --- a/tests.unit/database/test_inf_table.py +++ b/tests.unit/database/test_inf_table.py @@ -21,33 +21,35 @@ def test_valid_inf(empty_tree: Tree): """Tests that a valid Inf with typical settings is properly parsed.""" edk2path = Edk2Path(str(empty_tree.ws), []) db = Edk2DB(empty_tree.ws / "db.db", pathobj=edk2path) - db.register(InfTable(n_jobs = 1)) + db.register(InfTable(n_jobs=1)) # Configure inf libs = ["TestLib2", "TestLib3"] - protocols = ['gEfiTestProtocolGuid'] - guids = ['gEfiTestTokenSpaceGuid'] - sources = ['Test.c'] - sources_ia32 = ['IA32/Test.c'] - sources_x64 = ['X64/Test.c'] + protocols = ["gEfiTestProtocolGuid"] + guids = ["gEfiTestTokenSpaceGuid"] + sources = ["Test.c"] + sources_ia32 = ["IA32/Test.c"] + sources_x64 = ["X64/Test.c"] lib1 = empty_tree.create_library( - "TestLib1", "TestCls", - libraryclasses = libs, - protocols = protocols, - guids = guids, - sources = sources, - sources_ia32 = sources_ia32, - sources_x64 = sources_x64, + "TestLib1", + "TestCls", + libraryclasses=libs, + protocols=protocols, + guids=guids, + sources=sources, + sources_ia32=sources_ia32, + sources_x64=sources_x64, ) lib2 = empty_tree.create_library( - "TestLib2", "TestCls", - libraryclasses = libs, - protocols = protocols, - guids = guids, - sources = sources, - sources_ia32 = sources_ia32, - sources_x64 = sources_x64, + "TestLib2", + "TestCls", + libraryclasses=libs, + protocols=protocols, + guids=guids, + sources=sources, + sources_ia32=sources_ia32, + sources_x64=sources_x64, ) (empty_tree.library_folder / "IA32").mkdir() @@ -73,14 +75,8 @@ def test_source_path_with_dot_dot(empty_tree: Tree): """Tests that paths with .. are correctly resolved.""" edk2path = Edk2Path(str(empty_tree.ws), []) db = Edk2DB(empty_tree.ws / "db.db", pathobj=edk2path) - db.register(InfTable(n_jobs = 1)) - empty_tree.create_library( - "TestLib", "TestCls", - sources = [ - "../Test1.c", - "Test2.c" - ] - ) + db.register(InfTable(n_jobs=1)) + empty_tree.create_library("TestLib", "TestCls", sources=["../Test1.c", "Test2.c"]) file1 = empty_tree.package / "Test1.c" file1.touch() file2 = empty_tree.library_folder / "Test2.c" @@ -92,6 +88,7 @@ def test_source_path_with_dot_dot(empty_tree: Tree): for source in row.sources: assert empty_tree.ws / source.path in [file1, file2] + def test_pkg_not_pkg_path_relative(empty_tree: Tree): """Tests when a package is not itself relative to a package path. @@ -103,12 +100,7 @@ def test_pkg_not_pkg_path_relative(empty_tree: Tree): assert pkg1.relative == "Package1" assert pkg2.relative == "Packges/Package2" """ - empty_tree.create_library( - "TestLib", "TestCls", - sources = [ - "Test2.c" - ] - ) + empty_tree.create_library("TestLib", "TestCls", sources=["Test2.c"]) file2 = empty_tree.library_folder / "Test2.c" file2.touch() @@ -120,7 +112,7 @@ def test_pkg_not_pkg_path_relative(empty_tree: Tree): edk2path = Edk2Path(str(ws), []) db = Edk2DB(empty_tree.ws / "db.db", pathobj=edk2path) - db.register(InfTable(n_jobs = 1)) + db.register(InfTable(n_jobs=1)) db.parse({}) with db.session() as session: @@ -128,4 +120,3 @@ def test_pkg_not_pkg_path_relative(empty_tree: Tree): assert len(inf.sources) == 1 assert inf.sources[0].path == Path("Common", "TestPkg", "Library", "Test2.c").as_posix() assert inf.path == Path("Common", "TestPkg", "Library", "TestLib.inf").as_posix() - diff --git a/tests.unit/database/test_instanced_fv_table.py b/tests.unit/database/test_instanced_fv_table.py index 717f5961..83c92dfb 100644 --- a/tests.unit/database/test_instanced_fv_table.py +++ b/tests.unit/database/test_instanced_fv_table.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Unittest for the InstancedFv table generator.""" + import logging from pathlib import Path @@ -21,6 +22,7 @@ JOIN junction AS j ON ? = j.key1 and j.table2 = "inf" """ + def test_valid_fdf(empty_tree: Tree): # noqa: F811 """Tests that a typical fdf can be properly parsed.""" edk2path = Edk2Path(str(empty_tree.ws), []) @@ -42,22 +44,22 @@ def test_valid_fdf(empty_tree: Tree): # noqa: F811 dsc = empty_tree.create_dsc( libraryclasses=[], - components = [comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9], + components=[comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9], ) # Write the FDF; includes a "infformat" FV used to test # All the different ways an INF can be defined in the FDF fdf = empty_tree.create_fdf( - fv_testfv = [ - f"INF {comp1}", # PP relative - f'INF {str(empty_tree.ws / comp2)}', # Absolute - f'INF RuleOverride=RESET_VECTOR {comp3}', # RuleOverride - 'INF TestPkg/Extra Drivers/TestDriver4.inf', # Space in path - f'INF ruleoverride = RESET_VECTOR {comp5}', # RuleOverride lowercase & spaces' - f'INF USE = IA32 {comp6}', + fv_testfv=[ + f"INF {comp1}", # PP relative + f"INF {str(empty_tree.ws / comp2)}", # Absolute + f"INF RuleOverride=RESET_VECTOR {comp3}", # RuleOverride + "INF TestPkg/Extra Drivers/TestDriver4.inf", # Space in path + f"INF ruleoverride = RESET_VECTOR {comp5}", # RuleOverride lowercase & spaces' + f"INF USE = IA32 {comp6}", f'INF VERSION = "1.1.1" {comp7}', f'INF UI = "HELLO" {comp8}', - f'INF FILE_GUID = 12345678-1234-1234-1234-123456789012 {comp9}', + f"INF FILE_GUID = 12345678-1234-1234-1234-123456789012 {comp9}", ] ) env = { @@ -69,22 +71,25 @@ def test_valid_fdf(empty_tree: Tree): # noqa: F811 db.parse(env) with db.session() as session: - infs = session.query(Fv).filter_by(name = "testfv").one().infs + infs = session.query(Fv).filter_by(name="testfv").one().infs assert len(infs) == 9 - assert sorted([inf.path for inf in infs]) == sorted([ - Path(comp1).as_posix(), - Path(comp2).as_posix(), - Path(comp3).as_posix(), - 'TestPkg/Extra Drivers/TestDriver4.inf', - Path(comp5).as_posix(), - Path(comp6).as_posix(), - Path(comp7).as_posix(), - Path(comp8).as_posix(), - Path(comp9).as_posix(), - ]) - -def test_missing_dsc_and_fdf(empty_tree: Tree, caplog): + assert sorted([inf.path for inf in infs]) == sorted( + [ + Path(comp1).as_posix(), + Path(comp2).as_posix(), + Path(comp3).as_posix(), + "TestPkg/Extra Drivers/TestDriver4.inf", + Path(comp5).as_posix(), + Path(comp6).as_posix(), + Path(comp7).as_posix(), + Path(comp8).as_posix(), + Path(comp9).as_posix(), + ] + ) + + +def test_missing_dsc_and_fdf(empty_tree: Tree, caplog): # noqa: F811 """Tests that the table generator is skipped if missing the necessary information.""" with caplog.at_level(logging.DEBUG): edk2path = Edk2Path(str(empty_tree.ws), []) @@ -106,9 +111,8 @@ def test_missing_dsc_and_fdf(empty_tree: Tree, caplog): count += 1 assert count == 2 -def test_non_closest_inf_path(empty_tree: Tree): - +def test_non_closest_inf_path(empty_tree: Tree): # noqa: F811 # Create the Common folder, which will be a package path common_folder = empty_tree.ws / "Common" common_folder.mkdir() @@ -125,7 +129,7 @@ def test_non_closest_inf_path(empty_tree: Tree): dsc = empty_tree.create_dsc(libraryclasses=[], components=[driver]) fdf = empty_tree.create_fdf( - fv_testfv = [ + fv_testfv=[ "INF Common/SubFolder/Drivers/TestDriver1.inf", ] ) @@ -141,7 +145,7 @@ def test_non_closest_inf_path(empty_tree: Tree): db.parse(env) with db.session() as session: - libs = session.query(Fv).filter_by(name = "testfv").one().infs + libs = session.query(Fv).filter_by(name="testfv").one().infs assert len(libs) == 1 assert libs[0].path == "Drivers/TestDriver1.inf" diff --git a/tests.unit/database/test_instanced_inf_table.py b/tests.unit/database/test_instanced_inf_table.py index 4a5b460b..3ca12374 100644 --- a/tests.unit/database/test_instanced_inf_table.py +++ b/tests.unit/database/test_instanced_inf_table.py @@ -7,6 +7,7 @@ ## # ruff: noqa: F811 """unittests for the InfTable generator.""" + import logging from pathlib import Path @@ -26,6 +27,7 @@ AND ii.arch = ? """ + def test_valid_dsc(empty_tree: Tree): """Tests that a typical dsc can be correctly parsed.""" edk2path = Edk2Path(str(empty_tree.ws), []) @@ -35,8 +37,8 @@ def test_valid_dsc(empty_tree: Tree): comp1 = empty_tree.create_component("TestComponent1", "DXE_DRIVER") lib1 = empty_tree.create_library("TestLib1", "TestCls") dsc = empty_tree.create_dsc( - libraryclasses = [lib1], - components = [str(empty_tree.ws / comp1), lib1] # absolute comp path + libraryclasses=[lib1], + components=[str(empty_tree.ws / comp1), lib1], # absolute comp path ) env = { @@ -51,6 +53,7 @@ def test_valid_dsc(empty_tree: Tree): assert len(rows) == 1 assert rows[0].component == Path(comp1).as_posix() + def test_no_active_platform(empty_tree: Tree, caplog): """Tests that the dsc table returns immediately when no ACTIVE_PLATFORM is defined.""" caplog.set_level(logging.DEBUG) @@ -59,21 +62,22 @@ def test_no_active_platform(empty_tree: Tree, caplog): db.register(InstancedInfTable()) # Test 1: raise error for missing ACTIVE_PLATFORM - with pytest.raises(KeyError, match = "ACTIVE_PLATFORM"): + with pytest.raises(KeyError, match="ACTIVE_PLATFORM"): db.parse({}) # Test 2: raise error for missing TARGET_ARCH - with pytest.raises(KeyError, match = "TARGET_ARCH"): - db.parse({ - "ACTIVE_PLATFORM": "Test.dsc" - }) + with pytest.raises(KeyError, match="TARGET_ARCH"): + db.parse({"ACTIVE_PLATFORM": "Test.dsc"}) # Test 3: raise error for missing TARGET - with pytest.raises(KeyError, match = "TARGET"): - db.parse({ - "ACTIVE_PLATFORM": "Test.dsc", - "TARGET_ARCH": "IA32", - }) + with pytest.raises(KeyError, match="TARGET"): + db.parse( + { + "ACTIVE_PLATFORM": "Test.dsc", + "TARGET_ARCH": "IA32", + } + ) + def test_dsc_with_conditional(empty_tree: Tree): """Tests that conditionals inside a DSC works as expected.""" @@ -82,14 +86,9 @@ def test_dsc_with_conditional(empty_tree: Tree): db.register(InstancedInfTable()) empty_tree.create_library("TestLib", "SortLib") - comp1 = empty_tree.create_component('TestComponent1', 'DXE_DRIVER') + comp1 = empty_tree.create_component("TestComponent1", "DXE_DRIVER") - dsc = empty_tree.create_dsc( - components = [ - "!if $(TARGET) == \"RELEASE\"", - f"{comp1}", - "!endif" - ]) + dsc = empty_tree.create_dsc(components=['!if $(TARGET) == "RELEASE"', f"{comp1}", "!endif"]) env = { "ACTIVE_PLATFORM": dsc, @@ -102,6 +101,7 @@ def test_dsc_with_conditional(empty_tree: Tree): rows = session.query(InstancedInf).all() assert len(rows) == 0 + def test_library_override(empty_tree: Tree): """Tests that overrides and null library overrides can be parsed as expected.""" edk2path = Edk2Path(str(empty_tree.ws), []) @@ -112,24 +112,21 @@ def test_library_override(empty_tree: Tree): lib2 = empty_tree.create_library("TestLib2", "TestCls") lib3 = empty_tree.create_library("TestLib3", "TestNullCls") - comp1 = empty_tree.create_component( - "TestDriver1", "DXE_DRIVER", - libraryclasses = ["TestCls"] - ) + comp1 = empty_tree.create_component("TestDriver1", "DXE_DRIVER", libraryclasses=["TestCls"]) dsc = empty_tree.create_dsc( - libraryclasses = [ - f'TestCls|{lib1}', + libraryclasses=[ + f"TestCls|{lib1}", ], - components = [ - f'{comp1} {{', - '', + components=[ + f"{comp1} {{", + "", '!if $(TARGET) == "DEBUG"', - f'TestCls|{lib2}', - f'NULL|{lib3}', - '!endif', - '}', - ] + f"TestCls|{lib2}", + f"NULL|{lib3}", + "!endif", + "}", + ], ) env = { @@ -139,11 +136,12 @@ def test_library_override(empty_tree: Tree): } db.parse(env) with db.session() as session: - for entry in session.query(InstancedInf).filter_by(path = Path(comp1).as_posix()).all(): + for entry in session.query(InstancedInf).filter_by(path=Path(comp1).as_posix()).all(): assert len(entry.libraries) == 2 for library in entry.libraries: assert library.name in ["TestLib2", "TestLib3"] + def test_scoped_libraries1(empty_tree: Tree): """Ensure that the correct libraries in regards to scoping. @@ -156,21 +154,21 @@ def test_scoped_libraries1(empty_tree: Tree): db = Edk2DB(empty_tree.ws / "db.db", pathobj=edk2path) db.register(InstancedInfTable()) - lib1 = empty_tree.create_library("TestLib1", "TestCls", sources = ["File1.c"]) - lib2 = empty_tree.create_library("TestLib2", "TestCls", sources = ["File2.c"]) - lib3 = empty_tree.create_library("TestLib3", "TestCls", sources = ["File3.c"]) + lib1 = empty_tree.create_library("TestLib1", "TestCls", sources=["File1.c"]) + lib2 = empty_tree.create_library("TestLib2", "TestCls", sources=["File2.c"]) + lib3 = empty_tree.create_library("TestLib3", "TestCls", sources=["File3.c"]) - comp1 = empty_tree.create_component("TestDriver1", "PEIM", libraryclasses = ["TestCls"]) - comp2 = empty_tree.create_component("TestDriver2", "SEC", libraryclasses = ["TestCls"]) - comp3 = empty_tree.create_component("TestDriver3", "PEIM", libraryclasses = ["TestCls"]) + comp1 = empty_tree.create_component("TestDriver1", "PEIM", libraryclasses=["TestCls"]) + comp2 = empty_tree.create_component("TestDriver2", "SEC", libraryclasses=["TestCls"]) + comp3 = empty_tree.create_component("TestDriver3", "PEIM", libraryclasses=["TestCls"]) dsc = empty_tree.create_dsc( - libraryclasses = [f'TestCls|{lib1}'], - libraryclasses_ia32 = [f'TestCls|{lib2}'], - libraryclasses_ia32_peim = [f'TestCls|{lib3}'], - components = [], - components_x64 = [comp1], - components_ia32 = [comp2, comp3] + libraryclasses=[f"TestCls|{lib1}"], + libraryclasses_ia32=[f"TestCls|{lib2}"], + libraryclasses_ia32_peim=[f"TestCls|{lib3}"], + components=[], + components_x64=[comp1], + components_ia32=[comp2, comp3], ) env = { @@ -181,7 +179,7 @@ def test_scoped_libraries1(empty_tree: Tree): db.parse(env) with db.session() as session: - for component in session.query(InstancedInf).filter_by(cls = None).all(): + for component in session.query(InstancedInf).filter_by(cls=None).all(): assert len(component.libraries) == 1 component_path = Path(component.path) library_path = Path(component.libraries[0].path) @@ -192,6 +190,7 @@ def test_scoped_libraries1(empty_tree: Tree): for source in source_list: assert Path(source.path).name in ["File1.c", "File2.c", "File3.c"] + def test_scoped_libraries2(empty_tree: Tree): """Ensure that the correct libraries in regards to scoping. @@ -207,14 +206,14 @@ def test_scoped_libraries2(empty_tree: Tree): lib1 = empty_tree.create_library("TestLib1", "TestCls") lib2 = empty_tree.create_library("TestLib2", "TestCls") - comp1 = empty_tree.create_component("TestDriver1", "PEIM", libraryclasses = ["TestCls"]) - comp2 = empty_tree.create_component("TestDriver2", "SEC", libraryclasses = ["TestCls"]) + comp1 = empty_tree.create_component("TestDriver1", "PEIM", libraryclasses=["TestCls"]) + comp2 = empty_tree.create_component("TestDriver2", "SEC", libraryclasses=["TestCls"]) dsc = empty_tree.create_dsc( - libraryclasses_common_peim = [f'TestCls|{lib1}'], - libraryclasses = [f'TestCls|{lib2}'], - components = [], - components_x64 = [comp1, comp2], + libraryclasses_common_peim=[f"TestCls|{lib1}"], + libraryclasses=[f"TestCls|{lib2}"], + components=[], + components_x64=[comp1, comp2], ) env = { @@ -225,24 +224,25 @@ def test_scoped_libraries2(empty_tree: Tree): db.parse(env) with db.session() as session: - for component in session.query(InstancedInf).filter_by(cls = None).all(): + for component in session.query(InstancedInf).filter_by(cls=None).all(): assert len(component.libraries) == 1 component_path = Path(component.path) library_path = Path(component.libraries[0].path) assert library_path.name == component_path.name.replace("Driver", "Lib") + def test_missing_library(empty_tree: Tree): """Test when a library is missing.""" edk2path = Edk2Path(str(empty_tree.ws), []) db = Edk2DB(empty_tree.ws / "db.db", pathobj=edk2path) db.register(InstancedInfTable()) - comp1 = empty_tree.create_component("TestDriver1", "PEIM", libraryclasses = ["TestCls"]) + comp1 = empty_tree.create_component("TestDriver1", "PEIM", libraryclasses=["TestCls"]) dsc = empty_tree.create_dsc( - libraryclasses = [], - components = [], - components_x64 = [comp1], + libraryclasses=[], + components=[], + components_x64=[comp1], ) env = { @@ -257,28 +257,30 @@ def test_missing_library(empty_tree: Tree): # key2 = db.connection.execute("SELECT instanced_inf2 FROM instanced_inf_junction").fetchone()[0] # assert key2 is None # This library class does not have an instance available, so key2 should be None + def test_multiple_library_class(empty_tree: Tree): """Test that a library INF that has multiple library class definitions is handled correctly.""" edk2path = Edk2Path(str(empty_tree.ws), []) db = Edk2DB(":memory:", pathobj=edk2path) db.register(InstancedInfTable()) - lib1 = empty_tree.create_library("TestLib", "TestCls", default = { - "MODULE_TYPE": "BASE", - "BASE_NAME": "TestLib1", - "LIBRARY_CLASS 1": "TestCls1", - "LIBRARY_CLASS 2": "TestCls2", - }) + lib1 = empty_tree.create_library( + "TestLib", + "TestCls", + default={ + "MODULE_TYPE": "BASE", + "BASE_NAME": "TestLib1", + "LIBRARY_CLASS 1": "TestCls1", + "LIBRARY_CLASS 2": "TestCls2", + }, + ) - comp1 = empty_tree.create_component("TestDriver1", "DXE_RUNTIME_DRIVER", libraryclasses = ["TestCls1"]) - comp2 = empty_tree.create_component("TestDriver2", "DXE_DRIVER", libraryclasses = ["TestCls2"]) + comp1 = empty_tree.create_component("TestDriver1", "DXE_RUNTIME_DRIVER", libraryclasses=["TestCls1"]) + comp2 = empty_tree.create_component("TestDriver2", "DXE_DRIVER", libraryclasses=["TestCls2"]) dsc = empty_tree.create_dsc( - libraryclasses = [ - f'TestCls1|{lib1}', - f'TestCls2|{lib1}' - ], - components = [comp1, comp2], + libraryclasses=[f"TestCls1|{lib1}", f"TestCls2|{lib1}"], + components=[comp1, comp2], ) env = { @@ -290,15 +292,15 @@ def test_multiple_library_class(empty_tree: Tree): db.parse(env) with db.session() as session: - infs = session.query(InstancedInf).filter_by(cls = None ).all() + infs = session.query(InstancedInf).filter_by(cls=None).all() assert len(infs) == 2 - assert infs[0].path == Path(comp1).as_posix() # If this fails, The order of returned objects may have changed + assert infs[0].path == Path(comp1).as_posix() # If this fails, The order of returned objects may have changed assert len(infs[0].libraries) == 1 assert infs[0].libraries[0].path == Path(lib1).as_posix() assert infs[0].libraries[0].cls == "TestCls1" - assert infs[1].path == Path(comp2).as_posix() # If this fails, The order of returned objects may have changed + assert infs[1].path == Path(comp2).as_posix() # If this fails, The order of returned objects may have changed assert len(infs[1].libraries) == 1 assert infs[1].libraries[0].path == Path(lib1).as_posix() assert infs[1].libraries[0].cls == "TestCls2" @@ -313,10 +315,10 @@ def test_absolute_paths_in_dsc(empty_tree: Tree): comp1 = empty_tree.create_component("TestDriver", "DXE_DRIVER", libraryclasses=["TestCls"]) dsc = empty_tree.create_dsc( - libraryclasses = [ - f'TestCls| {str(empty_tree.ws / lib1)}', + libraryclasses=[ + f"TestCls| {str(empty_tree.ws / lib1)}", ], - components = [ + components=[ str(empty_tree.ws / comp1), ], ) @@ -335,6 +337,7 @@ def test_absolute_paths_in_dsc(empty_tree: Tree): assert rows[0].path == Path(lib1).as_posix() assert rows[1].path == Path(comp1).as_posix() + def test_closest_packagepath(empty_tree: Tree): common_folder = empty_tree.ws / "Common" common_folder.mkdir() @@ -353,11 +356,11 @@ def test_closest_packagepath(empty_tree: Tree): # Specify the file paths to be relative to the farther away package path dsc = empty_tree.create_dsc( - libraryclasses = [ - 'TestCls|SubFolder/Library/TestLib.inf', + libraryclasses=[ + "TestCls|SubFolder/Library/TestLib.inf", ], - components = [ - 'SubFolder/Drivers/TestDriver.inf', + components=[ + "SubFolder/Drivers/TestDriver.inf", ], ) @@ -378,6 +381,7 @@ def test_closest_packagepath(empty_tree: Tree): for row in rows: assert row.path.startswith(("Library", "Drivers")) + def test_dsc_with_component_section_moduletype_definition(empty_tree: Tree, caplog): """Component sections with a moduletype definition is not necessary and should be ignored. @@ -393,11 +397,11 @@ def test_dsc_with_component_section_moduletype_definition(empty_tree: Tree, capl comp1 = empty_tree.create_component("TestDriver", "PEIM", libraryclasses=["TestCls"]) dsc = empty_tree.create_dsc( - libraryclasses = [ - f'TestCls| {Path(lib1).as_posix()}', + libraryclasses=[ + f"TestCls| {Path(lib1).as_posix()}", ], - components = [], - components_ia32_PEIM = [ + components=[], + components_ia32_PEIM=[ Path(comp1).as_posix(), ], ) @@ -411,6 +415,7 @@ def test_dsc_with_component_section_moduletype_definition(empty_tree: Tree, capl # Should not error db.parse(env) + def test_dsc_with_null_lib_in_libraryclasses_section(empty_tree: Tree): edk2path = Edk2Path(str(empty_tree.ws), []) db = Edk2DB(empty_tree.ws / "db.db", pathobj=edk2path) @@ -424,23 +429,23 @@ def test_dsc_with_null_lib_in_libraryclasses_section(empty_tree: Tree): comp1 = empty_tree.create_component("TestDriver", "PEIM", libraryclasses=["TestCls"]) dsc = empty_tree.create_dsc( - libraryclasses = [ - f'TestCls| {Path(lib1).as_posix()}', - f'NULL| {Path(nulllib1).as_posix()}', + libraryclasses=[ + f"TestCls| {Path(lib1).as_posix()}", + f"NULL| {Path(nulllib1).as_posix()}", ], - libraryclasses_x64 = [ - f'NULL| {Path(nulllib2).as_posix()}', + libraryclasses_x64=[ + f"NULL| {Path(nulllib2).as_posix()}", ], - libraryclasses_x64_DXE_DRIVER = [ - f'NULL| {Path(nulllib3).as_posix()}', + libraryclasses_x64_DXE_DRIVER=[ + f"NULL| {Path(nulllib3).as_posix()}", ], - components = [], - components_ia32_PEIM = [ + components=[], + components_ia32_PEIM=[ Path(comp1).as_posix(), ], - components_x64 = [ + components_x64=[ Path(comp1).as_posix(), - ] + ], ) env = { @@ -452,7 +457,7 @@ def test_dsc_with_null_lib_in_libraryclasses_section(empty_tree: Tree): db.parse(env) with db.session() as session: - component = session.query(InstancedInf).filter_by(cls = None).one() + component = session.query(InstancedInf).filter_by(cls=None).one() assert len(component.libraries) == 2 db = Edk2DB(":memory:", pathobj=edk2path) @@ -466,5 +471,5 @@ def test_dsc_with_null_lib_in_libraryclasses_section(empty_tree: Tree): db.parse(env) with db.session() as session: - component = session.query(InstancedInf).filter_by(cls = None).one() + component = session.query(InstancedInf).filter_by(cls=None).one() assert len(component.libraries) == 3 diff --git a/tests.unit/database/test_source_table.py b/tests.unit/database/test_source_table.py index d782ea72..52bc4cf1 100644 --- a/tests.unit/database/test_source_table.py +++ b/tests.unit/database/test_source_table.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## """Tests for building a source file table.""" + from common import write_file # noqa: I001 from edk2toollib.database import Source, Edk2DB from edk2toollib.database.tables import SourceTable @@ -40,56 +41,58 @@ def test_source_with_license(tmp_path): """Tests that a source with a license is detected and the license is set.""" edk2path = Edk2Path(str(tmp_path), []) db = Edk2DB(tmp_path / "db.db", pathobj=edk2path) - db.register(SourceTable(n_jobs = 1)) + db.register(SourceTable(n_jobs=1)) # Verify we detect c and h files for file in ["file.c", "file.h", "file.asm", "file.cpp"]: - write_file(tmp_path / file, SOURCE_LICENSE) + write_file(tmp_path / file, SOURCE_LICENSE) db.parse({}) with db.session() as session: - rows = session.query(Source).all() - assert len(rows) == 4 - for entry in rows: - assert entry.license == "BSD-2-Clause-Patent" + rows = session.query(Source).all() + assert len(rows) == 4 + for entry in rows: + assert entry.license == "BSD-2-Clause-Patent" def test_source_without_license(tmp_path): """Tests that a source without a license is detected.""" edk2path = Edk2Path(str(tmp_path), []) db = Edk2DB(tmp_path / "db.db", pathobj=edk2path) - db.register(SourceTable(n_jobs = 1)) + db.register(SourceTable(n_jobs=1)) # Verify we detect c and h files for file in ["file.c", "file.h"]: - write_file(tmp_path / file, SOURCE_NO_LICENSE) + write_file(tmp_path / file, SOURCE_NO_LICENSE) db.parse({}) with db.session() as session: - rows = session.query(Source).all() - assert len(rows) == 2 - for entry in rows: - assert entry.license == "Unknown" + rows = session.query(Source).all() + assert len(rows) == 2 + for entry in rows: + assert entry.license == "Unknown" + def test_invalid_filetype(tmp_path): """Tests that a source file that is not of the valid type is skipped.""" edk2path = Edk2Path(str(tmp_path), []) db = Edk2DB(tmp_path / "db.db", pathobj=edk2path) - db.register(SourceTable(n_jobs = 1)) + db.register(SourceTable(n_jobs=1)) # Ensure we don't catch a file that isnt a c / h file. write_file(tmp_path / "file1.py", SOURCE_LICENSE) db.parse({}) with db.session() as session: - rows = session.query(Source).all() - assert len(rows) == 0 + rows = session.query(Source).all() + assert len(rows) == 0 + def test_source_with_code(tmp_path): """Tests that a source with code is detected.""" edk2path = Edk2Path(str(tmp_path), []) db = Edk2DB(tmp_path / "db.db", pathobj=edk2path) - db.register(SourceTable(n_jobs = 1, source_stats=True, source_extensions=["*.py"])) + db.register(SourceTable(n_jobs=1, source_stats=True, source_extensions=["*.py"])) # Verify we detect c and h files write_file(tmp_path / "file.py", SOURCE_WITH_CODE) @@ -97,14 +100,15 @@ def test_source_with_code(tmp_path): db.parse({}) with db.session() as session: - file = session.query(Source).one() - assert file.code_lines == 4 + file = session.query(Source).one() + assert file.code_lines == 4 + def test_source_with_code_is_updated(tmp_path): """Tests that a source with code is updated When parsed again with different source_stats setting.""" edk2path = Edk2Path(str(tmp_path), []) db = Edk2DB(tmp_path / "db.db", pathobj=edk2path) - db.register(SourceTable(n_jobs = 1, source_stats=False, source_extensions=["*.py"])) + db.register(SourceTable(n_jobs=1, source_stats=False, source_extensions=["*.py"])) # Verify we detect c and h files write_file(tmp_path / "file.py", SOURCE_WITH_CODE) @@ -112,13 +116,15 @@ def test_source_with_code_is_updated(tmp_path): db.parse({}) with db.session() as session: - file = session.query(Source).one() - assert file.code_lines == file.total_lines == 5 # When not parsing source_stats, code lines is equal to total lines + file = session.query(Source).one() + assert ( + file.code_lines == file.total_lines == 5 + ) # When not parsing source_stats, code lines is equal to total lines db.clear_parsers() - db.register(SourceTable(n_jobs = 1, source_stats=True, source_extensions=["*.py"])) + db.register(SourceTable(n_jobs=1, source_stats=True, source_extensions=["*.py"])) db.parse({}) with db.session() as session: - file = session.query(Source).one() - assert file.code_lines == 4 + file = session.query(Source).one() + assert file.code_lines == 4 diff --git a/tests.unit/parsers/test_base_parser.py b/tests.unit/parsers/test_base_parser.py index 4b6be58c..6a02d627 100644 --- a/tests.unit/parsers/test_base_parser.py +++ b/tests.unit/parsers/test_base_parser.py @@ -16,15 +16,9 @@ class TestBaseParser(unittest.TestCase): - def test_replace_boolean_constants(self): parser = BaseParser("") - parser.SetInputVars({ - "true": "True", - "false": "False", - "b_true": True, - "b_false": False - }) + parser.SetInputVars({"true": "True", "false": "False", "b_true": True, "b_false": False}) line = "$(true)" self.assertEqual(parser.ReplaceVariables(line), "TRUE") line = "$(false)" @@ -36,37 +30,28 @@ def test_replace_boolean_constants(self): def test_replace_macro_using_dollarsign(self): parser = BaseParser("") - parser.SetInputVars({ - "name": "sean" - }) + parser.SetInputVars({"name": "sean"}) line = "Hello $(name)!" self.assertEqual(parser.ReplaceVariables(line), "Hello sean!") def test_replace_macro_local_var_priority(self): parser = BaseParser("") - parser.SetInputVars({ - "name": "sean" - }) + parser.SetInputVars({"name": "sean"}) parser.LocalVars["name"] = "fred" line = "Hello $(name)!" self.assertEqual(parser.ReplaceVariables(line), "Hello fred!") class TestBaseParserConditionals(unittest.TestCase): - def test_replace_macro_without_resolution(self): parser = BaseParser("") - parser.SetInputVars({ - "name": "sean" - }) + parser.SetInputVars({"name": "sean"}) line = "!if $(Unknown_Token)!" self.assertEqual(parser.ReplaceVariables(line), "!if 0!") def test_replace_macro_ifdef_dollarsign(self): parser = BaseParser("") - parser.SetInputVars({ - "name": "sean" - }) + parser.SetInputVars({"name": "sean"}) line = "!ifdef $(name)" self.assertEqual(parser.ReplaceVariables(line), "!ifdef sean") @@ -78,9 +63,7 @@ def test_replace_macro_ifdef_dollarsign(self): def test_replace_macro_ifndef_dollarsign(self): parser = BaseParser("") - parser.SetInputVars({ - "name": "sean" - }) + parser.SetInputVars({"name": "sean"}) line = "!IfNDef $(name)" self.assertEqual(parser.ReplaceVariables(line), "!IfNDef sean") @@ -92,9 +75,7 @@ def test_replace_macro_ifndef_dollarsign(self): def test_replace_macro_ifdef(self): parser = BaseParser("") - parser.SetInputVars({ - "name": "sean" - }) + parser.SetInputVars({"name": "sean"}) line = "!ifdef name" self.assertEqual(parser.ReplaceVariables(line), "!ifdef sean") @@ -106,9 +87,7 @@ def test_replace_macro_ifdef(self): def test_replace_macro_ifndef(self): parser = BaseParser("") - parser.SetInputVars({ - "name": "sean" - }) + parser.SetInputVars({"name": "sean"}) line = "!IfNDef name" self.assertEqual(parser.ReplaceVariables(line), "!IfNDef sean") @@ -120,9 +99,7 @@ def test_replace_macro_ifndef(self): def test_replace_macro_elseif(self): parser = BaseParser("") - parser.SetInputVars({ - "name": "matt" - }) + parser.SetInputVars({"name": "matt"}) line = "!elseif $(name)" self.assertEqual(parser.ReplaceVariables(line), "!elseif matt") @@ -400,56 +377,57 @@ def test_process_conditional_reset(self): def test_process_in_conditional(self): parser = BaseParser("") parser.SetInputVars({"TOOL_CHAIN_TAG": "GCC5_TEST"}) - self.assertTrue(parser.ProcessConditional( - '!if ("GCC49" in $(TOOL_CHAIN_TAG)) OR ("GCC5" in $(TOOL_CHAIN_TAG))')) + self.assertTrue( + parser.ProcessConditional('!if ("GCC49" in $(TOOL_CHAIN_TAG)) OR ("GCC5" in $(TOOL_CHAIN_TAG))') + ) self.assertTrue(parser.InActiveCode()) parser.ResetParserState() parser.SetInputVars({"TOOL_CHAIN_TAG": "TESTGCC49"}) - self.assertTrue(parser.ProcessConditional( - '!if ("GCC49" in $(TOOL_CHAIN_TAG)) OR ("GCC5" in $(TOOL_CHAIN_TAG))')) + self.assertTrue( + parser.ProcessConditional('!if ("GCC49" in $(TOOL_CHAIN_TAG)) OR ("GCC5" in $(TOOL_CHAIN_TAG))') + ) self.assertTrue(parser.InActiveCode()) parser.ResetParserState() # Don't give it a tool chain tag that isn't in the things we're searching for parser.SetInputVars({"TOOL_CHAIN_TAG": "NOTFOUND"}) - self.assertTrue(parser.ProcessConditional( - '!if ("GCC49" in $(TOOL_CHAIN_TAG)) OR ("GCC5" in $(TOOL_CHAIN_TAG))')) + self.assertTrue( + parser.ProcessConditional('!if ("GCC49" in $(TOOL_CHAIN_TAG)) OR ("GCC5" in $(TOOL_CHAIN_TAG))') + ) self.assertFalse(parser.InActiveCode()) def test_process_or_operation_conditional(self): parser = BaseParser("") - self.assertTrue(parser.EvaluateConditional('!IF TRUE OR FALSE')) - self.assertTrue(parser.EvaluateConditional('!if FALSE OR TRUE')) - self.assertTrue(parser.EvaluateConditional('!if FALSE || TRUE')) - self.assertTrue(parser.EvaluateConditional('!if TRUE OR TRUE')) - self.assertFalse(parser.EvaluateConditional('!if FALSE OR FALSE')) - self.assertFalse(parser.EvaluateConditional('!if FALSE || FALSE')) + self.assertTrue(parser.EvaluateConditional("!IF TRUE OR FALSE")) + self.assertTrue(parser.EvaluateConditional("!if FALSE OR TRUE")) + self.assertTrue(parser.EvaluateConditional("!if FALSE || TRUE")) + self.assertTrue(parser.EvaluateConditional("!if TRUE OR TRUE")) + self.assertFalse(parser.EvaluateConditional("!if FALSE OR FALSE")) + self.assertFalse(parser.EvaluateConditional("!if FALSE || FALSE")) def test_process_and_operation_conditional(self): parser = BaseParser("") - self.assertFalse(parser.EvaluateConditional('!if TRUE AND FALSE')) - self.assertFalse(parser.EvaluateConditional('!if FALSE AND TRUE')) - self.assertTrue(parser.EvaluateConditional('!if TRUE AND TRUE')) - self.assertTrue(parser.EvaluateConditional('!if TRUE && TRUE')) - self.assertFalse(parser.EvaluateConditional('!if FALSE AND FALSE')) - self.assertFalse(parser.EvaluateConditional('!if FALSE && FALSE')) + self.assertFalse(parser.EvaluateConditional("!if TRUE AND FALSE")) + self.assertFalse(parser.EvaluateConditional("!if FALSE AND TRUE")) + self.assertTrue(parser.EvaluateConditional("!if TRUE AND TRUE")) + self.assertTrue(parser.EvaluateConditional("!if TRUE && TRUE")) + self.assertFalse(parser.EvaluateConditional("!if FALSE AND FALSE")) + self.assertFalse(parser.EvaluateConditional("!if FALSE && FALSE")) def test_process_invalid_conditional(self): parser = BaseParser("") with self.assertRaises(RuntimeError): - parser.EvaluateConditional('!if TRUE AND FALSE AND') + parser.EvaluateConditional("!if TRUE AND FALSE AND") with self.assertRaises(RuntimeError): - parser.EvaluateConditional('TRUE AND FALSE AND') + parser.EvaluateConditional("TRUE AND FALSE AND") def test_emulator_conditional_or_double_in(self): parser = BaseParser("") parser.SetInputVars({"ARCH": "X64"}) - self.assertTrue(parser.ProcessConditional( - '!if "IA32" in $(ARCH) || "X64" in $(ARCH)')) + self.assertTrue(parser.ProcessConditional('!if "IA32" in $(ARCH) || "X64" in $(ARCH)')) self.assertTrue(parser.InActiveCode()) parser.ResetParserState() parser.SetInputVars({"ARCH": "IA32"}) - self.assertTrue(parser.ProcessConditional( - '!if "IA32" in $(ARCH) || "X64" in $(ARCH)')) + self.assertTrue(parser.ProcessConditional('!if "IA32" in $(ARCH) || "X64" in $(ARCH)')) self.assertTrue(parser.InActiveCode()) parser.ResetParserState() @@ -461,86 +439,85 @@ def test_emulator_conditional_not_in(self): parser.ResetParserState() def test_emulator_conditional_parens_order(self): - '''Makes sure the parenthesis affect the order of expressions''' + """Makes sure the parenthesis affect the order of expressions""" parser = BaseParser("") - self.assertFalse(parser.EvaluateConditional('!if TRUE OR FALSE AND FALSE')) - self.assertTrue(parser.EvaluateConditional('!if TRUE OR (FALSE AND FALSE)')) + self.assertFalse(parser.EvaluateConditional("!if TRUE OR FALSE AND FALSE")) + self.assertTrue(parser.EvaluateConditional("!if TRUE OR (FALSE AND FALSE)")) parser.ResetParserState() def test_emulator_conditional_not_or(self): - '''Makes sure we can use the not with other operators''' + """Makes sure we can use the not with other operators""" parser = BaseParser("") - self.assertTrue(parser.EvaluateConditional('!if FALSE NOT OR FALSE')) - self.assertFalse(parser.EvaluateConditional('!if TRUE NOT OR FALSE')) - self.assertFalse(parser.EvaluateConditional('!if FALSE NOT OR TRUE')) - self.assertFalse(parser.EvaluateConditional('!if TRUE NOT OR TRUE')) + self.assertTrue(parser.EvaluateConditional("!if FALSE NOT OR FALSE")) + self.assertFalse(parser.EvaluateConditional("!if TRUE NOT OR FALSE")) + self.assertFalse(parser.EvaluateConditional("!if FALSE NOT OR TRUE")) + self.assertFalse(parser.EvaluateConditional("!if TRUE NOT OR TRUE")) def test_emulator_conditional_not_it_all(self): - '''Makes sure the parenthesis affect the order of expressions''' + """Makes sure the parenthesis affect the order of expressions""" parser = BaseParser("") - self.assertTrue(parser.EvaluateConditional('!if NOT FALSE OR FALSE')) - self.assertFalse(parser.EvaluateConditional('!if NOT TRUE OR FALSE')) + self.assertTrue(parser.EvaluateConditional("!if NOT FALSE OR FALSE")) + self.assertFalse(parser.EvaluateConditional("!if NOT TRUE OR FALSE")) # check to make sure it works with parenthesis - self.assertFalse(parser.EvaluateConditional('!if NOT(TRUE)')) - self.assertTrue(parser.EvaluateConditional('!if NOT(FALSE)')) + self.assertFalse(parser.EvaluateConditional("!if NOT(TRUE)")) + self.assertTrue(parser.EvaluateConditional("!if NOT(FALSE)")) # make sure it works with the bang symbol - self.assertFalse(parser.EvaluateConditional('!if !(TRUE)')) - self.assertTrue(parser.EvaluateConditional('!if !(FALSE)')) + self.assertFalse(parser.EvaluateConditional("!if !(TRUE)")) + self.assertTrue(parser.EvaluateConditional("!if !(FALSE)")) parser.ResetParserState() def test_conditional_with_variable(self): - '''Makes sure conversions are correct when using variables''' + """Makes sure conversions are correct when using variables""" parser = BaseParser("") - parser.LocalVars = {"MAX_SOCKET": '4', 'TARGET': 'DEBUG'} + parser.LocalVars = {"MAX_SOCKET": "4", "TARGET": "DEBUG"} - self.assertTrue(parser.ProcessConditional('!if $(MAX_SOCKET) <= 4')) + self.assertTrue(parser.ProcessConditional("!if $(MAX_SOCKET) <= 4")) self.assertTrue(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) self.assertTrue(parser.ProcessConditional('!if $(TARGET) == "DEBUG" && $(MAX_SOCKET) <= 4')) self.assertTrue(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) - self.assertTrue(parser.ProcessConditional('!if $(MAX_SOCKET) <= 3')) + self.assertTrue(parser.ProcessConditional("!if $(MAX_SOCKET) <= 3")) self.assertFalse(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) self.assertTrue(parser.ProcessConditional('!if ($(TARGET) == "RELEASE") && ($(MAX_SOCKET) <= 4)')) self.assertFalse(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) def test_conditional_without_spaces(self): parser = BaseParser("") - parser.LocalVars = {"MAX_SOCKET": '4'} + parser.LocalVars = {"MAX_SOCKET": "4"} - self.assertTrue(parser.ProcessConditional('!if $(MAX_SOCKET)<=4')) + self.assertTrue(parser.ProcessConditional("!if $(MAX_SOCKET)<=4")) self.assertTrue(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) - self.assertTrue(parser.ProcessConditional('!if $(MAX_SOCKET) <=4')) + self.assertTrue(parser.ProcessConditional("!if $(MAX_SOCKET) <=4")) self.assertTrue(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) - self.assertTrue(parser.ProcessConditional('!if $(MAX_SOCKET)<= 4')) + self.assertTrue(parser.ProcessConditional("!if $(MAX_SOCKET)<= 4")) self.assertTrue(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) - self.assertTrue(parser.ProcessConditional('!if $(MAX_SOCKET)>=4')) + self.assertTrue(parser.ProcessConditional("!if $(MAX_SOCKET)>=4")) self.assertTrue(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) - self.assertTrue(parser.ProcessConditional('!if $(MAX_SOCKET)==4')) + self.assertTrue(parser.ProcessConditional("!if $(MAX_SOCKET)==4")) self.assertTrue(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) - self.assertTrue(parser.ProcessConditional('!if $(MAX_SOCKET)!=3')) + self.assertTrue(parser.ProcessConditional("!if $(MAX_SOCKET)!=3")) self.assertTrue(parser.InActiveCode()) - self.assertTrue(parser.ProcessConditional('!endif')) + self.assertTrue(parser.ProcessConditional("!endif")) class TestBaseParserGuids(unittest.TestCase): - def test_is_guid(self): guid1 = "= { 0xD3B36F2C, 0xD551, 0x11D4, {0x9A, 0x46, 0x0, 0x90, 0x27, 0x3F, 0xC1,0xD }}" parser = BaseParser("") @@ -579,7 +556,6 @@ def test_parse_guid(self): class TestBaseParserVariables(unittest.TestCase): - def test_replace_input_variables(self): parser = BaseParser("") variables = { @@ -638,7 +614,6 @@ def test_replace_local_variables(self): class TestBaseParserPathAndFile(unittest.TestCase): - # because of how this works we use WriteLines, SetAbsPath, and SetPackagePath def test_find_path(self): # we're using write lines to make sure everything wo diff --git a/tests.unit/parsers/test_dec_parser.py b/tests.unit/parsers/test_dec_parser.py index cfae8431..478ccc61 100644 --- a/tests.unit/parsers/test_dec_parser.py +++ b/tests.unit/parsers/test_dec_parser.py @@ -22,9 +22,10 @@ class TestGuidDeclarationEntry(unittest.TestCase): - def test_valid_input_guid(self): - SAMPLE_DATA_GUID_DECL = '''gTestGuid = { 0x66341ae8, 0x668f, 0x4192, { 0xb4, 0x4d, 0x5f, 0x87, 0xb8, 0x68, 0xf0, 0x41 }}''' # noqa: E501 + SAMPLE_DATA_GUID_DECL = ( + """gTestGuid = { 0x66341ae8, 0x668f, 0x4192, { 0xb4, 0x4d, 0x5f, 0x87, 0xb8, 0x68, 0xf0, 0x41 }}""" # noqa: E501 + ) SAMPLE_DATA_GUID_STRING_REG_FORMAT = "{66341ae8-668f-4192-b44d-5f87b868f041}" a = GuidDeclarationEntry("TestPkg", SAMPLE_DATA_GUID_DECL) con = uuid.UUID(SAMPLE_DATA_GUID_STRING_REG_FORMAT) @@ -33,22 +34,27 @@ def test_valid_input_guid(self): self.assertEqual(a.package_name, "TestPkg") def test_valid_input_leading_zero_removed(self): - SAMPLE_DATA_GUID_DECL = '''gTestGuid = { 0x6341ae8, 0x68f, 0x192, { 0x4, 0xd, 0xf, 0x7, 0x8, 0x8, 0x0, 0x1 }}''' # noqa: E501 + SAMPLE_DATA_GUID_DECL = ( + """gTestGuid = { 0x6341ae8, 0x68f, 0x192, { 0x4, 0xd, 0xf, 0x7, 0x8, 0x8, 0x0, 0x1 }}""" # noqa: E501 + ) SAMPLE_DATA_GUID_STRING_REG_FORMAT = "{06341ae8-068f-0192-040d-0f0708080001}" a = GuidDeclarationEntry("testpkg", SAMPLE_DATA_GUID_DECL) con = uuid.UUID(SAMPLE_DATA_GUID_STRING_REG_FORMAT) self.assertEqual(str(con), str(a.guid)) def test_invalid_guid_format(self): - SAMPLE_DATA_GUID_DECL = '''gTestGuid = 0x6341ae8, 0x668f, 0x4192, 0xb4, 0x4d, 0x5f, 0x87, 0xb8, 0x68, 0xf0, 0x41''' # noqa: E501 + SAMPLE_DATA_GUID_DECL = ( + """gTestGuid = 0x6341ae8, 0x668f, 0x4192, 0xb4, 0x4d, 0x5f, 0x87, 0xb8, 0x68, 0xf0, 0x41""" # noqa: E501 + ) with self.assertRaises(ValueError): GuidDeclarationEntry("testpkg", SAMPLE_DATA_GUID_DECL) class TestPpiDeclarationEntry(unittest.TestCase): - def test_valid_input_guid(self): - SAMPLE_DATA_PPI_DECL = """gTestPpiGuid = {0xa66cd455, 0xc078, 0x4753, {0xbe, 0x93, 0xdd, 0x58, 0xb2, 0xaf, 0xe9, 0xc4}}""" # noqa: E501 + SAMPLE_DATA_PPI_DECL = ( + """gTestPpiGuid = {0xa66cd455, 0xc078, 0x4753, {0xbe, 0x93, 0xdd, 0x58, 0xb2, 0xaf, 0xe9, 0xc4}}""" # noqa: E501 + ) SAMPLE_DATA_PPI_STRING_REG_FORMAT = "{a66cd455-c078-4753-be93-dd58b2afe9c4}" a = PpiDeclarationEntry("testpkg", SAMPLE_DATA_PPI_DECL) con = uuid.UUID(SAMPLE_DATA_PPI_STRING_REG_FORMAT) @@ -58,9 +64,10 @@ def test_valid_input_guid(self): class TestProtocolDeclarationEntry(unittest.TestCase): - def test_valid_input_guid(self): - SAMPLE_DATA_PROTOCOL_DECL = """gTestProtocolGuid = {0xb6d12b5a, 0x5338, 0x44ac, {0xac, 0x31, 0x1e, 0x9f, 0xa8, 0xc7, 0xe0, 0x1e}}""" # noqa: E501 + SAMPLE_DATA_PROTOCOL_DECL = ( + """gTestProtocolGuid = {0xb6d12b5a, 0x5338, 0x44ac, {0xac, 0x31, 0x1e, 0x9f, 0xa8, 0xc7, 0xe0, 0x1e}}""" # noqa: E501 + ) SAMPLE_DATA_PROTOCOL_GUID_REG_FORMAT = "{b6d12b5a-5338-44ac-ac31-1e9fa8c7e01e}" a = ProtocolDeclarationEntry("testpkg", SAMPLE_DATA_PROTOCOL_DECL) con = uuid.UUID(SAMPLE_DATA_PROTOCOL_GUID_REG_FORMAT) @@ -70,7 +77,6 @@ def test_valid_input_guid(self): class TestLibraryClassDeclarationEntry(unittest.TestCase): - def test_valid_input(self): SAMPLE_DATA_DECL = """BmpSupportLib|Include/Library/BmpSupportLib.h""" a = LibraryClassDeclarationEntry("testpkg", SAMPLE_DATA_DECL) @@ -79,7 +85,6 @@ def test_valid_input(self): class TestPcdDeclarationEntry(unittest.TestCase): - def test_valid_input(self): SAMPLE_DATA_DECL = """gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE|BOOLEAN|0x0001001d""" a = PcdDeclarationEntry("testpkg", SAMPLE_DATA_DECL) @@ -115,7 +120,7 @@ def test_string_containing_a_pipe(self): a = PcdDeclarationEntry("testpkg", SAMPLE_DATA_DECL) self.assertEqual(a.token_space_name, "gTestTokenSpaceGuid") self.assertEqual(a.name, "PcdTestString") - self.assertEqual(a.default_value, "L\"TestVal_1 | TestVal_2\"") + self.assertEqual(a.default_value, 'L"TestVal_1 | TestVal_2"') self.assertEqual(a.type, "VOID*") self.assertEqual(a.id, "0x00010001") @@ -132,14 +137,13 @@ def test_string_containing_single_quote(self): a = PcdDeclarationEntry("testpkg", SAMPLE_DATA_DECL) self.assertEqual(a.token_space_name, "gTestTokenSpaceGuid") self.assertEqual(a.name, "PcdTestString") - self.assertEqual(a.default_value, "\"eng'fraengfra\"") + self.assertEqual(a.default_value, '"eng\'fraengfra"') self.assertEqual(a.type, "VOID*") self.assertEqual(a.id, "0x00010001") -class TestDecParser(unittest.TestCase): - SAMPLE_DEC_FILE = \ - """## @file +class TestDecParser(unittest.TestCase): + SAMPLE_DEC_FILE = """## @file TestDecFile ## diff --git a/tests.unit/parsers/test_dmar_parser.py b/tests.unit/parsers/test_dmar_parser.py index f3e2084f..b635d008 100644 --- a/tests.unit/parsers/test_dmar_parser.py +++ b/tests.unit/parsers/test_dmar_parser.py @@ -11,7 +11,6 @@ class DmarParserTest(unittest.TestCase): - dse_t_01h = None dse_t_03h = None dse_t_04h = None @@ -40,15 +39,15 @@ def test_dmar_parser_dse_01h(self): def test_dmar_parser_dse_03h(self): # IOAPIC - dse_t_03h = bytes([0x03, 0x08, 0x00, 0x00, 0x02, 0xf0, 0x1f, 0x00]) + dse_t_03h = bytes([0x03, 0x08, 0x00, 0x00, 0x02, 0xF0, 0x1F, 0x00]) DmarParserTest.dse_t_03h = DMARTable.DeviceScopeStruct(dse_t_03h) self.assertNotEqual(DmarParserTest.dse_t_03h, None) self.assertEqual(DmarParserTest.dse_t_03h.Type, 0x03) self.assertEqual(DmarParserTest.dse_t_03h.Length, 0x08) self.assertEqual(DmarParserTest.dse_t_03h.Reserved, 0) self.assertEqual(DmarParserTest.dse_t_03h.EnumerationID, 0x02) - self.assertEqual(DmarParserTest.dse_t_03h.StartBusNumber, 0xf0) - self.assertEqual(DmarParserTest.dse_t_03h.Path[0], ((0x1f,), (0x00,))) + self.assertEqual(DmarParserTest.dse_t_03h.StartBusNumber, 0xF0) + self.assertEqual(DmarParserTest.dse_t_03h.Path[0], ((0x1F,), (0x00,))) self.assertEqual(DmarParserTest.dse_t_03h.TypeString, "IOAPIC") try: @@ -59,7 +58,7 @@ def test_dmar_parser_dse_03h(self): def test_dmar_parser_dse_04h(self): # MSI_CAPABLE_HPET - dse_t_04h = bytes([0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00]) + dse_t_04h = bytes([0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00]) DmarParserTest.dse_t_04h = DMARTable.DeviceScopeStruct(dse_t_04h) self.assertNotEqual(DmarParserTest.dse_t_04h, None) self.assertEqual(DmarParserTest.dse_t_04h.Type, 0x04) @@ -67,7 +66,7 @@ def test_dmar_parser_dse_04h(self): self.assertEqual(DmarParserTest.dse_t_04h.Reserved, 0) self.assertEqual(DmarParserTest.dse_t_04h.EnumerationID, 0x00) self.assertEqual(DmarParserTest.dse_t_04h.StartBusNumber, 0x00) - self.assertEqual(DmarParserTest.dse_t_04h.Path[0], ((0x1f,), (0x00,))) + self.assertEqual(DmarParserTest.dse_t_04h.Path[0], ((0x1F,), (0x00,))) self.assertEqual(DmarParserTest.dse_t_04h.TypeString, "MSI_CAPABLE_HPET") try: @@ -78,12 +77,26 @@ def test_dmar_parser_dse_04h(self): def test_dmar_parser_drhd(self): # DRHD header - drhd_t = bytes([0x00, 0x00, # Type - 0x10, 0x00, # Length - 0x00, # Flags - 0x00, # Reserved - 0x00, 0x00, # Segment Number - 0x00, 0x00, 0xd9, 0xfe, 0x00, 0x00, 0x00, 0x00]) # Register Base Address + drhd_t = bytes( + [ + 0x00, + 0x00, # Type + 0x10, + 0x00, # Length + 0x00, # Flags + 0x00, # Reserved + 0x00, + 0x00, # Segment Number + 0x00, + 0x00, + 0xD9, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + ] + ) # Register Base Address DmarParserTest.drhd_t = DMARTable.DRHDStruct(drhd_t, len(drhd_t)) self.assertNotEqual(DmarParserTest.drhd_t, None) @@ -93,7 +106,7 @@ def test_dmar_parser_drhd(self): self.assertEqual(DmarParserTest.drhd_t.Flags, 0x00) self.assertEqual(DmarParserTest.drhd_t.Reserved, 0x00) self.assertEqual(DmarParserTest.drhd_t.SegmentNumber, 0x0000) - self.assertEqual(DmarParserTest.drhd_t.RegisterBaseAddress, 0x00000000fed90000) + self.assertEqual(DmarParserTest.drhd_t.RegisterBaseAddress, 0x00000000FED90000) try: drhd_xml = DmarParserTest.drhd_t.toXml() @@ -109,12 +122,34 @@ def test_dmar_parser_drhd(self): def test_dmar_parser_rmrr(self): # RMRR header - rmrr_t = bytes([0x01, 0x00, # Type - 0x18, 0x00, # Length - 0x00, 0x00, # Reserved - 0x00, 0x00, # SegmentNumber - 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, # ReservedMemoryBaseAddress - 0xff, 0xff, 0x7f, 0x8f, 0x00, 0x00, 0x00, 0x00]) # ReservedMemoryRegionLimitAddress + rmrr_t = bytes( + [ + 0x01, + 0x00, # Type + 0x18, + 0x00, # Length + 0x00, + 0x00, # Reserved + 0x00, + 0x00, # SegmentNumber + 0x00, + 0x00, + 0x00, + 0x8D, + 0x00, + 0x00, + 0x00, + 0x00, # ReservedMemoryBaseAddress + 0xFF, + 0xFF, + 0x7F, + 0x8F, + 0x00, + 0x00, + 0x00, + 0x00, + ] + ) # ReservedMemoryRegionLimitAddress DmarParserTest.rmrr_t = DMARTable.RMRRStruct(rmrr_t, len(rmrr_t)) self.assertNotEqual(DmarParserTest.rmrr_t, None) @@ -123,8 +158,8 @@ def test_dmar_parser_rmrr(self): self.assertEqual(DmarParserTest.rmrr_t.Length, 0x18) self.assertEqual(DmarParserTest.rmrr_t.Reserved, 0x00) self.assertEqual(DmarParserTest.rmrr_t.SegmentNumber, 0x00) - self.assertEqual(DmarParserTest.rmrr_t.ReservedMemoryBaseAddress, 0x8d000000) - self.assertEqual(DmarParserTest.rmrr_t.ReservedMemoryRegionLimitAddress, 0x8f7fffff) + self.assertEqual(DmarParserTest.rmrr_t.ReservedMemoryBaseAddress, 0x8D000000) + self.assertEqual(DmarParserTest.rmrr_t.ReservedMemoryRegionLimitAddress, 0x8F7FFFFF) try: rmrr_xml = DmarParserTest.rmrr_t.toXml() @@ -140,30 +175,70 @@ def test_dmar_parser_rmrr(self): def test_dmar_parser_acpi_header(self): # Just ACPI header only - dmar_header = bytes([0x44, 0x4d, 0x41, 0x52, # Signature: DMAR - 0x30, 0x00, 0x00, 0x00, # Length - 0x01, # Revision - 0xad, # Checksum - 0x4d, 0x53, 0x46, 0x54, 0x20, 0x20, # OEM ID: 'MSFT ' - 0x4d, 0x53, 0x46, 0x54, 0x20, 0x20, 0x20, 0x20, # OEM Table ID: 'MSFT ' - 0x01, 0x00, 0x00, 0x00, # OEM Revision - 0x49, 0x4e, 0x54, 0x4c, # CreatorID: 'INTL' - 0x01, 0x00, 0x00, 0x00, # Creator revision - 0x26, # HostAddressWidth - 0x05, # Flags - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) # Reserved + dmar_header = bytes( + [ + 0x44, + 0x4D, + 0x41, + 0x52, # Signature: DMAR + 0x30, + 0x00, + 0x00, + 0x00, # Length + 0x01, # Revision + 0xAD, # Checksum + 0x4D, + 0x53, + 0x46, + 0x54, + 0x20, + 0x20, # OEM ID: 'MSFT ' + 0x4D, + 0x53, + 0x46, + 0x54, + 0x20, + 0x20, + 0x20, + 0x20, # OEM Table ID: 'MSFT ' + 0x01, + 0x00, + 0x00, + 0x00, # OEM Revision + 0x49, + 0x4E, + 0x54, + 0x4C, # CreatorID: 'INTL' + 0x01, + 0x00, + 0x00, + 0x00, # Creator revision + 0x26, # HostAddressWidth + 0x05, # Flags + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ] + ) # Reserved acpi_header = DMARTable.AcpiTableHeader(dmar_header) self.assertNotEqual(acpi_header, None) - self.assertEqual(acpi_header.Signature, b'DMAR') + self.assertEqual(acpi_header.Signature, b"DMAR") self.assertEqual(acpi_header.Length, 0x30) self.assertEqual(acpi_header.Revision, 0x01) - self.assertEqual(acpi_header.Checksum, 0xad) - self.assertEqual(acpi_header.OEMID, b'MSFT ') - self.assertEqual(acpi_header.OEMTableID, b'MSFT ') + self.assertEqual(acpi_header.Checksum, 0xAD) + self.assertEqual(acpi_header.OEMID, b"MSFT ") + self.assertEqual(acpi_header.OEMTableID, b"MSFT ") self.assertEqual(acpi_header.OEMRevision, 1) - self.assertEqual(acpi_header.CreatorID, b'INTL') + self.assertEqual(acpi_header.CreatorID, b"INTL") self.assertEqual(acpi_header.CreatorRevision, 1) self.assertEqual(acpi_header.HostAddressWidth, 0x26) self.assertEqual(acpi_header.Flags, 0x05) @@ -182,23 +257,146 @@ def test_dmar_parser_acpi_header(self): def test_dmar_parser_ivrs_full(self): # finally a real deal, just to see if they are stitched properly - full_table = bytes([0x44, 0x4d, 0x41, 0x52, 0x88, 0x00, 0x00, 0x00, - 0x01, 0xad, 0x4d, 0x53, 0x46, 0x54, 0x20, 0x20, - 0x4d, 0x53, 0x46, 0x54, 0x20, 0x20, 0x20, 0x20, - 0x01, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x54, 0x4c, - 0x01, 0x00, 0x00, 0x00, 0x26, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xd9, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x10, 0xd9, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x08, 0x00, 0x00, 0x02, 0xf0, 0x1f, 0x00, - 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, - 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x7f, 0x8f, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00]) + full_table = bytes( + [ + 0x44, + 0x4D, + 0x41, + 0x52, + 0x88, + 0x00, + 0x00, + 0x00, + 0x01, + 0xAD, + 0x4D, + 0x53, + 0x46, + 0x54, + 0x20, + 0x20, + 0x4D, + 0x53, + 0x46, + 0x54, + 0x20, + 0x20, + 0x20, + 0x20, + 0x01, + 0x00, + 0x00, + 0x00, + 0x49, + 0x4E, + 0x54, + 0x4C, + 0x01, + 0x00, + 0x00, + 0x00, + 0x26, + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x18, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xD9, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x08, + 0x00, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x20, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x10, + 0xD9, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x08, + 0x00, + 0x00, + 0x02, + 0xF0, + 0x1F, + 0x00, + 0x04, + 0x08, + 0x00, + 0x00, + 0x00, + 0x00, + 0x1F, + 0x00, + 0x01, + 0x00, + 0x20, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x8D, + 0x00, + 0x00, + 0x00, + 0x00, + 0xFF, + 0xFF, + 0x7F, + 0x8F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x08, + 0x00, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + ] + ) dmar_table = DMARTable(full_table) self.assertEqual(dmar_table.ANDDCount(), 0) @@ -220,5 +418,5 @@ def test_dmar_parser_ivrs_full(self): self.assertFalse(False, "Failed to convert DMAR object to string") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests.unit/parsers/test_dsc_parser.py b/tests.unit/parsers/test_dsc_parser.py index 7c349087..226c3b8d 100644 --- a/tests.unit/parsers/test_dsc_parser.py +++ b/tests.unit/parsers/test_dsc_parser.py @@ -15,14 +15,12 @@ class TestDscParserBasic(unittest.TestCase): - def test_creation(self): a = DscParser() self.assertNotEqual(a, None) class TestDscParserIncludes(unittest.TestCase): - @staticmethod def write_to_file(file_path, data): f = open(file_path, "w") @@ -30,7 +28,7 @@ def write_to_file(file_path, data): f.close() def test_dsc_include_single_file(self): - ''' This tests whether includes work properly ''' + """This tests whether includes work properly""" workspace = tempfile.mkdtemp() file1_name = "file1.dsc" @@ -53,7 +51,7 @@ def test_dsc_include_single_file(self): self.assertEqual(len(parser.GetAllDscPaths()), 2) # make sure we have two dsc paths def test_dsc_include_missing_file(self): - ''' This tests whether includes work properly ''' + """This tests whether includes work properly""" workspace = tempfile.mkdtemp() file1_name = "file1.dsc" @@ -69,7 +67,7 @@ def test_dsc_include_missing_file(self): parser.ParseFile(file1_path) def test_dsc_include_missing_file_no_fail_mode(self): - ''' This tests whether includes work properly if no fail mode is on''' + """This tests whether includes work properly if no fail mode is on""" workspace = tempfile.mkdtemp() file1_name = "file1.dsc" @@ -85,7 +83,7 @@ def test_dsc_include_missing_file_no_fail_mode(self): parser.ParseFile(file1_path) def test_dsc_parse_file_on_package_path(self): - ''' This tests whether includes work properly if no fail mode is on''' + """This tests whether includes work properly if no fail mode is on""" workspace = tempfile.mkdtemp() working_dir_name = "working" working2_dir_name = "working2" @@ -108,12 +106,16 @@ def test_dsc_parse_file_on_package_path(self): parser = DscParser() parser.SetEdk2Path(Edk2Path(workspace, [])) - parser.SetPackagePaths([working_folder, ]) + parser.SetPackagePaths( + [ + working_folder, + ] + ) parser.ParseFile(file1_short_path) self.assertEqual(parser.LocalVars["INCLUDED"], "TRUE") # make sure we got the defines def test_dsc_include_relative_path(self): - ''' This tests whether includes work properly with a relative path''' + """This tests whether includes work properly with a relative path""" workspace = tempfile.mkdtemp() outside_folder = os.path.join(workspace, "outside") inside_folder = os.path.join(outside_folder, "inside") @@ -125,7 +127,6 @@ def test_dsc_include_relative_path(self): cwd = os.getcwd() os.chdir(random_folder) try: - file1_name = "file1.dsc" file1_path = os.path.join(outside_folder, file1_name) diff --git a/tests.unit/parsers/test_fdf_parser.py b/tests.unit/parsers/test_fdf_parser.py index a5e01cd3..178a321c 100644 --- a/tests.unit/parsers/test_fdf_parser.py +++ b/tests.unit/parsers/test_fdf_parser.py @@ -18,63 +18,62 @@ class TestBasicFdfParser(unittest.TestCase): - def test_primary_defines(self): - test_fdf = os.path.join(TEST_PATH, 'SimpleDefines.fdf') + test_fdf = os.path.join(TEST_PATH, "SimpleDefines.fdf") parser = FdfParser().SetEdk2Path(Edk2Path(TEST_PATH, [])) parser.ParseFile(test_fdf) # Make sure that we can read local variables out of the file. - self.assertEqual(parser.Dict['FD_BASE'], '0x00800000') - self.assertEqual(parser.Dict['NUM_BLOCKS'], '0x410') + self.assertEqual(parser.Dict["FD_BASE"], "0x00800000") + self.assertEqual(parser.Dict["NUM_BLOCKS"], "0x410") self.assertFalse("EXTRA_DEF" in parser.Dict) def test_primary_conditional_defines(self): - test_fdf = os.path.join(TEST_PATH, 'SimpleDefines.fdf') + test_fdf = os.path.join(TEST_PATH, "SimpleDefines.fdf") parser = FdfParser().SetEdk2Path(Edk2Path(TEST_PATH, [])).SetInputVars({"TARGET": "TEST2"}) parser.ParseFile(test_fdf) # Make sure that we can read local variables out of the file. - self.assertEqual(parser.Dict['FD_BASE'], '0x00800000') - self.assertEqual(parser.Dict['NUM_BLOCKS'], '0x850') + self.assertEqual(parser.Dict["FD_BASE"], "0x00800000") + self.assertEqual(parser.Dict["NUM_BLOCKS"], "0x850") self.assertTrue("EXTRA_DEF" in parser.Dict) def test_included_defines(self): - test_fdf = os.path.join(TEST_PATH, 'IncludedDefinesParent.fdf') + test_fdf = os.path.join(TEST_PATH, "IncludedDefinesParent.fdf") parser = FdfParser().SetEdk2Path(Edk2Path(TEST_PATH, [])) parser.ParseFile(test_fdf) # Make sure that we can read local variables out of the file. - self.assertEqual(parser.Dict['FD_BASE'], '0x00800000') - self.assertEqual(parser.Dict['EXTRA_BLOCK_SIZE'], '0x00001000') + self.assertEqual(parser.Dict["FD_BASE"], "0x00800000") + self.assertEqual(parser.Dict["EXTRA_BLOCK_SIZE"], "0x00001000") self.assertFalse("AM_I_YOU" in parser.Dict) def test_included_conditional_defines(self): - test_fdf = os.path.join(TEST_PATH, 'IncludedDefinesParent.fdf') + test_fdf = os.path.join(TEST_PATH, "IncludedDefinesParent.fdf") pathobj = Edk2Path(TEST_PATH, []) parser = FdfParser().SetEdk2Path(pathobj) parser = FdfParser().SetEdk2Path(pathobj).SetInputVars({"TARGET": "TEST4"}) parser.ParseFile(test_fdf) # Make sure that we can read local variables out of the file. - self.assertEqual(parser.Dict['FD_BASE'], '0x00800000') - self.assertEqual(parser.Dict['EXTRA_BLOCK_SIZE'], '0x00001000') - self.assertEqual(parser.Dict['NUM_BLOCKS'], '0x410') + self.assertEqual(parser.Dict["FD_BASE"], "0x00800000") + self.assertEqual(parser.Dict["EXTRA_BLOCK_SIZE"], "0x00001000") + self.assertEqual(parser.Dict["NUM_BLOCKS"], "0x410") self.assertTrue("AM_I_YOU" in parser.Dict) self.assertFalse("CONDITIONAL_VALUE" in parser.Dict) def test_conditionally_included_defines(self): - test_fdf = os.path.join(TEST_PATH, 'IncludedDefinesParent.fdf') + test_fdf = os.path.join(TEST_PATH, "IncludedDefinesParent.fdf") pathobj = Edk2Path(TEST_PATH, []) parser = FdfParser().SetEdk2Path(pathobj) parser = FdfParser().SetEdk2Path(pathobj).SetInputVars({"TARGET": "TEST5"}) parser.ParseFile(test_fdf) # Make sure that we can read local variables out of the file. - self.assertEqual(parser.Dict['FD_BASE'], '0x00800000') - self.assertEqual(parser.Dict['INTERNAL_VALUE'], '104') - self.assertEqual(parser.Dict['NUM_BLOCKS'], '0x410') - self.assertEqual(parser.Dict['CONDITIONAL_VALUE'], '121') + self.assertEqual(parser.Dict["FD_BASE"], "0x00800000") + self.assertEqual(parser.Dict["INTERNAL_VALUE"], "104") + self.assertEqual(parser.Dict["NUM_BLOCKS"], "0x410") + self.assertEqual(parser.Dict["CONDITIONAL_VALUE"], "121") def test_section_guided(): @@ -88,7 +87,7 @@ def test_section_guided(): } """) try: - with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', delete=False) as f: + with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=False) as f: f.write(SAMPLE_FDF_FILE) fdf_path = f.name @@ -99,5 +98,6 @@ def test_section_guided(): os.remove(fdf_path) # Then - assert "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" in \ - parser.FVs["MAINFV"]["Files"]["aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"] + assert ( + "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" in parser.FVs["MAINFV"]["Files"]["aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"] + ) diff --git a/tests.unit/parsers/test_gitingore_parser.py b/tests.unit/parsers/test_gitingore_parser.py index 723390e8..56e77050 100644 --- a/tests.unit/parsers/test_gitingore_parser.py +++ b/tests.unit/parsers/test_gitingore_parser.py @@ -45,6 +45,7 @@ def BuildGitIgnore(root): class GitIgnoreParserTest(unittest.TestCase): """Tests for the gitignore parser.""" + def test_gitignoreparser_filter(self): """Ensure the gitignore parser filters files and folders correctly. @@ -84,8 +85,8 @@ def test_gitignoreparser_filter(self): # Example line in a .gitignore # *_extdep - self.assertTrue(rule_tester(root / 'test_extdep')) - self.assertTrue(rule_tester(root / 'T' / 'test_extdep')) + self.assertTrue(rule_tester(root / "test_extdep")) + self.assertTrue(rule_tester(root / "T" / "test_extdep")) # Test a rule which specifies that a file of a specific type at any # depth is correctly filtered. @@ -103,20 +104,20 @@ def test_gitignoreparser_filter(self): # Example line in a .gitignore # *.exe # !important.exe - self.assertTrue(rule_tester(root / 'test.exe')) - self.assertTrue(rule_tester(root / 'T' / 'test.exe')) - self.assertFalse(rule_tester(root / 'important.exe')) - self.assertFalse(rule_tester(root / 'T' / 'important.exe')) + self.assertTrue(rule_tester(root / "test.exe")) + self.assertTrue(rule_tester(root / "T" / "test.exe")) + self.assertFalse(rule_tester(root / "important.exe")) + self.assertFalse(rule_tester(root / "T" / "important.exe")) # Test a rule which specifies a file type in any directory under a # specific folder are correctly filtered. # Example line in a .gitignore # /docs/**/*.txt - self.assertTrue(rule_tester(root / 'docs' / 'notes.txt')) - self.assertFalse(rule_tester(root / 'docs' / 'Readme.md')) - self.assertTrue(rule_tester(root / 'docs' / 'developing' / 'notes.txt')) - self.assertFalse(rule_tester(root / 'docs' / 'developing' / 'Readme.md')) + self.assertTrue(rule_tester(root / "docs" / "notes.txt")) + self.assertFalse(rule_tester(root / "docs" / "Readme.md")) + self.assertTrue(rule_tester(root / "docs" / "developing" / "notes.txt")) + self.assertFalse(rule_tester(root / "docs" / "developing" / "Readme.md")) # Test a rule which specifies a file with a specific naming convention be # correctly filtered @@ -124,19 +125,19 @@ def test_gitignoreparser_filter(self): # Example line in a .gitignore # out?.log - self.assertTrue(rule_tester(root / 'out1.log')) - self.assertTrue(rule_tester(root / 'outF.log')) - self.assertFalse(rule_tester(root / 'out11.log')) + self.assertTrue(rule_tester(root / "out1.log")) + self.assertTrue(rule_tester(root / "outF.log")) + self.assertFalse(rule_tester(root / "out11.log")) # log[0-9].txt - self.assertTrue(rule_tester(root / 'log1.txt')) - self.assertFalse(rule_tester(root / 'logF.txt')) - self.assertFalse(rule_tester(root / 'log11.txt')) + self.assertTrue(rule_tester(root / "log1.txt")) + self.assertFalse(rule_tester(root / "logF.txt")) + self.assertFalse(rule_tester(root / "log11.txt")) # log0[!a-z].txt - self.assertTrue(rule_tester(root / 'log01.txt')) - self.assertFalse(rule_tester(root / 'log0a.txt')) - self.assertTrue(rule_tester(root / 'log0A.txt')) + self.assertTrue(rule_tester(root / "log01.txt")) + self.assertFalse(rule_tester(root / "log0a.txt")) + self.assertTrue(rule_tester(root / "log0A.txt")) def test_rule_from_pattern(self): """Tests general expected functionality of rule_from_pattern.""" @@ -149,152 +150,161 @@ def test_rule_from_pattern(self): self.assertIsNone(gitignore_parser.rule_from_pattern("# Comment", root)) self.assertIsNone(gitignore_parser.rule_from_pattern(" ", root)) + def test_ignore_no_extensions(tmp_path): - """Tests that files without an extension can be ignored.""" - root = tmp_path.resolve() - gitignore_path = root / ".gitignore" - with open(gitignore_path, 'w') as f: - f.write("*\n") - f.write("!*.*\n") - f.write("!*/\n") + """Tests that files without an extension can be ignored.""" + root = tmp_path.resolve() + gitignore_path = root / ".gitignore" + with open(gitignore_path, "w") as f: + f.write("*\n") + f.write("!*.*\n") + f.write("!*/\n") - rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path) + rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path) + + assert rule_tester(root / "File.txt") is False + assert rule_tester(root / "executable") is True - assert rule_tester(root / "File.txt") is False - assert rule_tester(root / "executable") is True + assert rule_tester(root / "files" / "file.txt") is False + assert rule_tester(root / "bins" / "run_me") is True - assert rule_tester(root / "files" / "file.txt") is False - assert rule_tester(root / "bins" / "run_me") is True def test_pound_in_filename(tmp_path): r"""Tests that a # symbol is escaped if prefixed with a \\.""" root = tmp_path.resolve() gitignore_path = root / ".gitignore" - with open(gitignore_path, 'w') as f: + with open(gitignore_path, "w") as f: f.write("#file.txt\n") - f.write("\\#file.txt\n" ) + f.write("\\#file.txt\n") rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path) assert rule_tester(root / "file.txt") is False assert rule_tester(root / "#file.txt") is True + def test_test_trailingspace(tmp_path): """Tests that trailing spaces are not ignored.""" root = tmp_path.resolve() gitignore_path = root / ".gitignore" - with open(gitignore_path, 'w') as f: - f.write('ignoretrailingspace \n') - f.write('notignoredspace\\ \n') - f.write('partiallyignoredspace\\ \n') - f.write('partiallyignoredspace2 \\ \n') - f.write('notignoredmultiplespace\\ \\ \\ ') - - rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir='/home/tmp') - - assert rule_tester('/home/tmp/ignoretrailingspace') is True - assert rule_tester('/home/tmp/ignoretrailingspace ') is False - assert rule_tester('/home/tmp/partiallyignoredspace ') is True - assert rule_tester('/home/tmp/partiallyignoredspace ') is False - assert rule_tester('/home/tmp/partiallyignoredspace') is False - assert rule_tester('/home/tmp/partiallyignoredspace2 ') is True - assert rule_tester('/home/tmp/partiallyignoredspace2 ') is False - assert rule_tester('/home/tmp/partiallyignoredspace2 ') is False - assert rule_tester('/home/tmp/partiallyignoredspace2') is False - assert rule_tester('/home/tmp/notignoredspace ') is True - assert rule_tester('/home/tmp/notignoredspace') is False - assert rule_tester('/home/tmp/notignoredmultiplespace ') is True - assert rule_tester('/home/tmp/notignoredmultiplespace') is False + with open(gitignore_path, "w") as f: + f.write("ignoretrailingspace \n") + f.write("notignoredspace\\ \n") + f.write("partiallyignoredspace\\ \n") + f.write("partiallyignoredspace2 \\ \n") + f.write("notignoredmultiplespace\\ \\ \\ ") + + rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir="/home/tmp") + + assert rule_tester("/home/tmp/ignoretrailingspace") is True + assert rule_tester("/home/tmp/ignoretrailingspace ") is False + assert rule_tester("/home/tmp/partiallyignoredspace ") is True + assert rule_tester("/home/tmp/partiallyignoredspace ") is False + assert rule_tester("/home/tmp/partiallyignoredspace") is False + assert rule_tester("/home/tmp/partiallyignoredspace2 ") is True + assert rule_tester("/home/tmp/partiallyignoredspace2 ") is False + assert rule_tester("/home/tmp/partiallyignoredspace2 ") is False + assert rule_tester("/home/tmp/partiallyignoredspace2") is False + assert rule_tester("/home/tmp/notignoredspace ") is True + assert rule_tester("/home/tmp/notignoredspace") is False + assert rule_tester("/home/tmp/notignoredmultiplespace ") is True + assert rule_tester("/home/tmp/notignoredmultiplespace") is False + def test_slash_in_range_does_not_match_dirs(tmp_path): """Tests that a slash in a range does not match directories.""" root = tmp_path.resolve() gitignore_path = root / ".gitignore" - with open(gitignore_path, 'w') as f: - f.write('abc[X-Z/]def\n') + with open(gitignore_path, "w") as f: + f.write("abc[X-Z/]def\n") + + rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir="/home/tmp") - rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir = '/home/tmp') + assert rule_tester("/home/tmp/abcdef") is False + assert rule_tester("/home/tmp/abcXdef") is True + assert rule_tester("/home/tmp/abcYdef") is True + assert rule_tester("/home/tmp/abcZdef") is True + assert rule_tester("/home/tmp/abc/def") is False + assert rule_tester("/home/tmp/abcXYZdef") is False - assert rule_tester('/home/tmp/abcdef') is False - assert rule_tester('/home/tmp/abcXdef') is True - assert rule_tester('/home/tmp/abcYdef') is True - assert rule_tester('/home/tmp/abcZdef') is True - assert rule_tester('/home/tmp/abc/def') is False - assert rule_tester('/home/tmp/abcXYZdef') is False def test_incomplete_filename(tmp_path): """Tests that an incomplete filename is not matched.""" root = tmp_path.resolve() gitignore_path = root / ".gitignore" - with open(gitignore_path, 'w') as f: - f.write('o.py\n') + with open(gitignore_path, "w") as f: + f.write("o.py\n") + + rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir="/home/tmp") - rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir = '/home/tmp') + assert rule_tester("/home/tmp/o.py") is True + assert rule_tester("/home/tmp/foo.py") is False + assert rule_tester("/home/tmp/o.pyc") is False + assert rule_tester("/home/tmp/dir/o.py") is True + assert rule_tester("/home/tmp/dir/foo.py") is False + assert rule_tester("/home/tmp/dir/o.pyc") is False - assert rule_tester('/home/tmp/o.py') is True - assert rule_tester('/home/tmp/foo.py') is False - assert rule_tester('/home/tmp/o.pyc') is False - assert rule_tester('/home/tmp/dir/o.py') is True - assert rule_tester('/home/tmp/dir/foo.py') is False - assert rule_tester('/home/tmp/dir/o.pyc') is False def test_double_asterisks(tmp_path): """Test that double asterisk match any number of directories.""" root = tmp_path.resolve() gitignore_path = root / ".gitignore" - with open(gitignore_path, 'w') as f: - f.write('foo/**/Bar\n') + with open(gitignore_path, "w") as f: + f.write("foo/**/Bar\n") + + rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir="/home/tmp") + assert rule_tester("/home/tmp/foo/hello/Bar") is True + assert rule_tester("/home/tmp/foo/world/Bar") is True + assert rule_tester("/home/tmp/foo/Bar") is True + assert rule_tester("/home/tmp/foo/BarBar") is False - rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir='/home/tmp') - assert rule_tester('/home/tmp/foo/hello/Bar') is True - assert rule_tester('/home/tmp/foo/world/Bar') is True - assert rule_tester('/home/tmp/foo/Bar') is True - assert rule_tester('/home/tmp/foo/BarBar') is False def test_double_asterisk_without_slashes_handled_like_single_asterisk(tmp_path): """Test that a double asterisk without slashes is treated like a single asterisk.""" root = tmp_path.resolve() gitignore_path = root / ".gitignore" - with open(gitignore_path, 'w') as f: - f.write('a/b**c/d\n') + with open(gitignore_path, "w") as f: + f.write("a/b**c/d\n") + + rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir="/home/tmp") + assert rule_tester("/home/tmp//a/bc/d") is True + assert rule_tester("/home/tmp//a/bXc/d") is True + assert rule_tester("/home/tmp//a/bbc/d") is True + assert rule_tester("/home/tmp//a/bcc/d") is True + assert rule_tester("/home/tmp//a/bcd") is False + assert rule_tester("/home/tmp//a/b/c/d") is False + assert rule_tester("/home/tmp//a/bb/cc/d") is False + assert rule_tester("/home/tmp//a/bb/XX/cc/d") is False - rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir='/home/tmp') - assert rule_tester('/home/tmp//a/bc/d') is True - assert rule_tester('/home/tmp//a/bXc/d') is True - assert rule_tester('/home/tmp//a/bbc/d') is True - assert rule_tester('/home/tmp//a/bcc/d') is True - assert rule_tester('/home/tmp//a/bcd') is False - assert rule_tester('/home/tmp//a/b/c/d') is False - assert rule_tester('/home/tmp//a/bb/cc/d') is False - assert rule_tester('/home/tmp//a/bb/XX/cc/d') is False def test_more_asterisks_handled_like_single_asterisk(tmp_path): """Test that multiple asterisk in a row are treated as a single astrick.""" root = tmp_path.resolve() gitignore_path = root / ".gitignore" - with open(gitignore_path, 'w') as f: - f.write('***a/b\n') + with open(gitignore_path, "w") as f: + f.write("***a/b\n") - rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir='/home/tmp') - assert rule_tester('/home/tmp//XYZa/b') is True - assert rule_tester('/home/tmp//foo/a/b') is False + rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir="/home/tmp") + assert rule_tester("/home/tmp//XYZa/b") is True + assert rule_tester("/home/tmp//foo/a/b") is False gitignore_path = root / ".gitignore2" - with open(gitignore_path, 'w') as f: - f.write('a/b***\n') + with open(gitignore_path, "w") as f: + f.write("a/b***\n") + + rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir="/home/tmp") - rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir='/home/tmp') + assert rule_tester("/home/tmp//a/bXYZ") is True + assert rule_tester("/home/tmp//a/b/foo") is False - assert rule_tester('/home/tmp//a/bXYZ') is True - assert rule_tester('/home/tmp//a/b/foo') is False def test_symlink_to_another_directory(): """Test the behavior of a symlink to another directory. @@ -308,17 +318,17 @@ def test_symlink_to_another_directory(): another_dir = Path(another_dir).resolve() gitignore_path = project_dir / ".gitignore" - with open(gitignore_path, 'w') as f: - f.write('link\n') + with open(gitignore_path, "w") as f: + f.write("link\n") rule_tester = gitignore_parser.parse_gitignore_file(gitignore_path, base_dir=project_dir) # Create a symlink to another directory. - link = project_dir / 'link' - target = another_dir / 'target' + link = project_dir / "link" + target = another_dir / "target" try: link.symlink_to(target) - except OSError: # Missing permissions to do a symlink + except OSError: # Missing permissions to do a symlink skip("Current user does not have permissions to perform symlink.") # Check the intended behavior according to diff --git a/tests.unit/parsers/test_guid_parser.py b/tests.unit/parsers/test_guid_parser.py index 7db4d124..3ffc10cc 100644 --- a/tests.unit/parsers/test_guid_parser.py +++ b/tests.unit/parsers/test_guid_parser.py @@ -12,7 +12,6 @@ class TestGuidParser(unittest.TestCase): - def test_valid_input_guid(self): SAMPLE_DATA_C_FORMAT_GUID = "{0x66341ae8, 0x668f, 0x4192, {0xb4, 0x4d, 0x5f, 0x87, 0xb8, 0x68, 0xf0, 0x41}}" # noqa: E501 SAMPLE_DATA_REG_FORMAT_GUID = "66341ae8-668f-4192-b44d-5f87b868f041" @@ -22,11 +21,11 @@ def test_valid_input_guid(self): uuid_from_c = GuidParser.uuid_from_guidstring(SAMPLE_DATA_C_FORMAT_GUID) uuid_from_reg = GuidParser.uuid_from_guidstring(SAMPLE_DATA_REG_FORMAT_GUID) - self.assertEqual(GuidParser.reg_guid_str_from_uuid(uuid_from_c), - GuidParser.reg_guid_str_from_uuid(uuid_from_reg)) + self.assertEqual( + GuidParser.reg_guid_str_from_uuid(uuid_from_c), GuidParser.reg_guid_str_from_uuid(uuid_from_reg) + ) - self.assertEqual(GuidParser.c_guid_str_from_uuid(uuid_from_c), - GuidParser.c_guid_str_from_uuid(uuid_from_reg)) + self.assertEqual(GuidParser.c_guid_str_from_uuid(uuid_from_c), GuidParser.c_guid_str_from_uuid(uuid_from_reg)) def test_invalid_reg_format_to_uuid(self): SAMPLE_DATA_REG_FORMAT_GUID = "66341ae8-668f4192b44d-0087b868f041" @@ -36,7 +35,7 @@ def test_invalid_reg_format_to_uuid(self): def test_invalid_reg_format_to_c_format(self): SAMPLE_DATA_REG_FORMAT_GUID = "66341ae8-668f4192b44d-0087b868f041" u = GuidParser.c_guid_from_reg_format(SAMPLE_DATA_REG_FORMAT_GUID) - self.assertEqual('', u) + self.assertEqual("", u) def test_invalid_c_format_to_uuid(self): SAMPLE_DATA_C_FORMAT_GUID = "{0x66341ae8, 0x668f 0x4192 {0xb4, 0x4d, 0x5f, 0x87, 0xb8, 0x68, 0xf0, 0x41}}" @@ -44,27 +43,31 @@ def test_invalid_c_format_to_uuid(self): self.assertIsNone(u) def test_invalid_c_format_to_reg(self): - SAMPLE_DATA_C_FORMAT_GUID = "{0x66341ae8, 0x668f4192, 0x1234, {0xb4, 0x4d, 0x5f34, 0x87, 0xb8, 0x68, 0xf0, 0x41}}" # noqa: E501 + SAMPLE_DATA_C_FORMAT_GUID = ( + "{0x66341ae8, 0x668f4192, 0x1234, {0xb4, 0x4d, 0x5f34, 0x87, 0xb8, 0x68, 0xf0, 0x41}}" # noqa: E501 + ) u = GuidParser.reg_guid_from_c_format(SAMPLE_DATA_C_FORMAT_GUID) - self.assertEqual('', u) + self.assertEqual("", u) def test_valid_reg_input_with_brackets(self): - """ check the reg_format functions are able to handle extra {} as reg format sometimes has brackets """ + """check the reg_format functions are able to handle extra {} as reg format sometimes has brackets""" SAMPLE_DATA_REG_FORMAT_GUID_WITH = "{66341ae8-668f-4192-b44d-5f87b868f041}" SAMPLE_DATA_REG_FORMAT_GUID = "66341ae8-668f-4192-b44d-5f87b868f041" u = GuidParser.uuid_from_guidstring(SAMPLE_DATA_REG_FORMAT_GUID_WITH) self.assertEqual(SAMPLE_DATA_REG_FORMAT_GUID, GuidParser.reg_guid_str_from_uuid(u)) def test_valid_reg_input_with_spaces(self): - """ check the reg_format functions are able to handle extra spaces """ + """check the reg_format functions are able to handle extra spaces""" SAMPLE_DATA_REG_FORMAT_GUID_WITH = " 66341ae8-668f-4192-b44d-5f87b868f041 " SAMPLE_DATA_REG_FORMAT_GUID = "66341ae8-668f-4192-b44d-5f87b868f041" u = GuidParser.uuid_from_guidstring(SAMPLE_DATA_REG_FORMAT_GUID_WITH) self.assertEqual(SAMPLE_DATA_REG_FORMAT_GUID, GuidParser.reg_guid_str_from_uuid(u)) def test_valid_c_format_input_with_spaces(self): - """ check the c_format functions are able to handle extra spaces """ - SAMPLE_DATA_C_FORMAT_GUID = " { 0x66341ae8, 0x668f, 0x4192, {0xb4, 0x4d, 0x5f, 0x87, 0xb8, 0x68, 0xf0, 0x41 } } " # noqa: E501 + """check the c_format functions are able to handle extra spaces""" + SAMPLE_DATA_C_FORMAT_GUID = ( + " { 0x66341ae8, 0x668f, 0x4192, {0xb4, 0x4d, 0x5f, 0x87, 0xb8, 0x68, 0xf0, 0x41 } } " # noqa: E501 + ) SAMPLE_DATA_REG_FORMAT_GUID = "66341ae8-668f-4192-b44d-5f87b868f041" u = GuidParser.uuid_from_guidstring(SAMPLE_DATA_C_FORMAT_GUID) self.assertEqual(SAMPLE_DATA_REG_FORMAT_GUID, GuidParser.reg_guid_str_from_uuid(u)) diff --git a/tests.unit/parsers/test_hash_file_parser.py b/tests.unit/parsers/test_hash_file_parser.py index 37770286..e806b4fb 100644 --- a/tests.unit/parsers/test_hash_file_parser.py +++ b/tests.unit/parsers/test_hash_file_parser.py @@ -13,7 +13,6 @@ class TestBaseParser(unittest.TestCase): - def test_parse_new_section(self): parser = HashFileParser("") section1 = "[Defines]" @@ -47,14 +46,14 @@ def test_strip_comment(self): ("gMyPkgTokenSpaceGuid.MyThing|'Value'|VOID*|0x10000000", " # My Comment"), ('gMyPkgTokenSpaceGuid.MyThing|"Value"|VOID*|0x10000000', "# My Comment"), ('gMyPkgTokenSpaceGuid.MyThing|"#Value"|VOID*|0x10000000', "# My Comment"), - ('file_data = "DEFINE TEST DEFINE = \"DEFINE_VALUE\""', ' # "Test String" # Test String'), + ('file_data = "DEFINE TEST DEFINE = "DEFINE_VALUE""', ' # "Test String" # Test String'), ("file_data = 'DEFINE TEST DEFINE = \"DEFINE_VALUE\"'", ' # "Test String" # Test String'), - ('file_data = "DEFINE TEST DEFINE = \"DEFINE_VALUE\" \' more to check \'"', ' # "Test String" # Test String'), - ('file_data = \'DEFINE\" # TEMP \" UPDATE \'', "# Found a quote"), - (r'test = \"', r' # Temp \"'), - ('file_data = "DEFINE TEST DEFINE = \"DEFINE\\"_VALUE\""', ' # "Test String" # Test String'), - ('file_data = "DEFINE TEST DEFINE = \"DEFINE\\\'_VALUE\""', ' # "Test String" # Test String'), + ('file_data = "DEFINE TEST DEFINE = "DEFINE_VALUE" \' more to check \'"', ' # "Test String" # Test String'), + ("file_data = 'DEFINE\" # TEMP \" UPDATE '", "# Found a quote"), + (r"test = \"", r" # Temp \""), + ('file_data = "DEFINE TEST DEFINE = "DEFINE\\"_VALUE""', ' # "Test String" # Test String'), + ('file_data = "DEFINE TEST DEFINE = "DEFINE\\\'_VALUE""', ' # "Test String" # Test String'), ] for line in lines_to_test: - self.assertEqual(parser.StripComment(line[0]+line[1]), line[0]) + self.assertEqual(parser.StripComment(line[0] + line[1]), line[0]) diff --git a/tests.unit/parsers/test_inf_parser.py b/tests.unit/parsers/test_inf_parser.py index 263579b9..611e70ed 100644 --- a/tests.unit/parsers/test_inf_parser.py +++ b/tests.unit/parsers/test_inf_parser.py @@ -49,6 +49,7 @@ $(MY_PATH)/File6.c """ + def test_inf_parser_scoped_libraryclasses(tmp_path: Path): """Test that we accurately detect scoped library classes.""" inf_path = tmp_path / "test.inf" @@ -63,6 +64,7 @@ def test_inf_parser_scoped_libraryclasses(tmp_path: Path): assert sorted(infp.get_libraries(["IA32"])) == sorted(["Library1", "Library2", "Library3", "Library4"]) assert sorted(infp.get_libraries(["X64"])) == sorted(["Library1", "Library2", "Library4"]) + def test_inf_parser_scoped_sources(tmp_path: Path): """Test that we accurately detect scoped sources.""" inf_path = tmp_path / "test.inf" @@ -77,6 +79,7 @@ def test_inf_parser_scoped_sources(tmp_path: Path): assert sorted(infp.get_sources(["IA32"])) == sorted(["File1.c", "File2.c", "File3.c", "File4.c"]) assert sorted(infp.get_sources(["X64"])) == sorted(["File1.c", "File2.c", "File4.c"]) + def test_inf_parser_with_defines(tmp_path: Path): """Tests that we accurately resolve variables if defined in the INF.""" inf_path = tmp_path / "test.inf" diff --git a/tests.unit/parsers/test_ivrs_parser.py b/tests.unit/parsers/test_ivrs_parser.py index ce2c339f..1f55a057 100644 --- a/tests.unit/parsers/test_ivrs_parser.py +++ b/tests.unit/parsers/test_ivrs_parser.py @@ -11,7 +11,6 @@ class IvrsParserTest(unittest.TestCase): - dte_00h = None dte_01h = None dte_02h = None @@ -129,70 +128,167 @@ def test_ivrs_parser_dte_48h(self): def test_ivrs_parser_dte_f0h_0(self): # ACPI device without UID - dte_t_f0h_0 = bytes([0xF0, 0x11, 0x11, 0xF6, - 0x46, 0x41, 0x4B, 0x45, 0x30, 0x30, 0x30, 0x30, # HID: 'FAKE0000' - 0x43, 0x4F, 0x4D, 0x50, 0x30, 0x30, 0x30, 0x30, # CID: 'COMP0000' - 0x00, # UID format - 0x00]) # UID length + dte_t_f0h_0 = bytes( + [ + 0xF0, + 0x11, + 0x11, + 0xF6, + 0x46, + 0x41, + 0x4B, + 0x45, + 0x30, + 0x30, + 0x30, + 0x30, # HID: 'FAKE0000' + 0x43, + 0x4F, + 0x4D, + 0x50, + 0x30, + 0x30, + 0x30, + 0x30, # CID: 'COMP0000' + 0x00, # UID format + 0x00, + ] + ) # UID length IvrsParserTest.dte_f0h_0 = IVRS_TABLE.DEVICE_TABLE_ENTRY.Factory(dte_t_f0h_0) self.assertNotEqual(IvrsParserTest.dte_f0h_0.Encode(), None) self.assertEqual(IvrsParserTest.dte_f0h_0.Type, IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ACPI) self.assertEqual(IvrsParserTest.dte_f0h_0.DeviceID, 0x1111) self.assertEqual(IvrsParserTest.dte_f0h_0.DTESetting, 0xF6) - self.assertEqual(IvrsParserTest.dte_f0h_0.HID, b'FAKE0000') - self.assertEqual(IvrsParserTest.dte_f0h_0.CID, b'COMP0000') + self.assertEqual(IvrsParserTest.dte_f0h_0.HID, b"FAKE0000") + self.assertEqual(IvrsParserTest.dte_f0h_0.CID, b"COMP0000") self.assertEqual(IvrsParserTest.dte_f0h_0.UIDFormat, 0x00) self.assertEqual(IvrsParserTest.dte_f0h_0.UIDLength, 0x00) def test_ivrs_parser_dte_f0h_1(self): # ACPI device with integer UID - dte_t_f0h_1 = bytes([0xF0, 0x11, 0x11, 0xF6, - 0x46, 0x41, 0x4B, 0x45, 0x30, 0x30, 0x30, 0x30, # HID: 'FAKE0000' - 0x43, 0x4F, 0x4D, 0x50, 0x30, 0x30, 0x30, 0x30, # CID: 'COMP0000' - 0x01, # UID format - 0x08, # UID length - 0x0D, 0xF0, 0xED, 0xFE, 0xEF, 0xBE, 0xAD, 0xDE]) # UID: 0xDEADBEEFFEEDF00D + dte_t_f0h_1 = bytes( + [ + 0xF0, + 0x11, + 0x11, + 0xF6, + 0x46, + 0x41, + 0x4B, + 0x45, + 0x30, + 0x30, + 0x30, + 0x30, # HID: 'FAKE0000' + 0x43, + 0x4F, + 0x4D, + 0x50, + 0x30, + 0x30, + 0x30, + 0x30, # CID: 'COMP0000' + 0x01, # UID format + 0x08, # UID length + 0x0D, + 0xF0, + 0xED, + 0xFE, + 0xEF, + 0xBE, + 0xAD, + 0xDE, + ] + ) # UID: 0xDEADBEEFFEEDF00D IvrsParserTest.dte_f0h_1 = IVRS_TABLE.DEVICE_TABLE_ENTRY.Factory(dte_t_f0h_1) self.assertNotEqual(IvrsParserTest.dte_f0h_1.Encode(), None) self.assertEqual(IvrsParserTest.dte_f0h_1.Type, IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ACPI) self.assertEqual(IvrsParserTest.dte_f0h_1.DeviceID, 0x1111) self.assertEqual(IvrsParserTest.dte_f0h_1.DTESetting, 0xF6) - self.assertEqual(IvrsParserTest.dte_f0h_1.HID, b'FAKE0000') - self.assertEqual(IvrsParserTest.dte_f0h_1.CID, b'COMP0000') + self.assertEqual(IvrsParserTest.dte_f0h_1.HID, b"FAKE0000") + self.assertEqual(IvrsParserTest.dte_f0h_1.CID, b"COMP0000") self.assertEqual(IvrsParserTest.dte_f0h_1.UIDFormat, 0x01) self.assertEqual(IvrsParserTest.dte_f0h_1.UIDLength, 0x08) self.assertEqual(IvrsParserTest.dte_f0h_1.UID, 0xDEADBEEFFEEDF00D) def test_ivrs_parser_dte_f0h_2(self): # ACPI device with string UID - dte_t_f0h_2 = bytes([0xF0, 0x11, 0x11, 0xF6, - 0x46, 0x41, 0x4B, 0x45, 0x30, 0x30, 0x30, 0x30, # HID: 'FAKE0000' - 0x43, 0x4F, 0x4D, 0x50, 0x30, 0x30, 0x30, 0x30, # CID: 'COMP0000' - 0x02, # UID format - 0x09, # UID length - 0x5C, 0x5F, 0x53, 0x42, 0x2E, 0x46, 0x55, 0x52, 0x30]) # UID: '\_SB.FUR0' + dte_t_f0h_2 = bytes( + [ + 0xF0, + 0x11, + 0x11, + 0xF6, + 0x46, + 0x41, + 0x4B, + 0x45, + 0x30, + 0x30, + 0x30, + 0x30, # HID: 'FAKE0000' + 0x43, + 0x4F, + 0x4D, + 0x50, + 0x30, + 0x30, + 0x30, + 0x30, # CID: 'COMP0000' + 0x02, # UID format + 0x09, # UID length + 0x5C, + 0x5F, + 0x53, + 0x42, + 0x2E, + 0x46, + 0x55, + 0x52, + 0x30, + ] + ) # UID: '\_SB.FUR0' IvrsParserTest.dte_f0h_2 = IVRS_TABLE.DEVICE_TABLE_ENTRY.Factory(dte_t_f0h_2) self.assertNotEqual(IvrsParserTest.dte_f0h_2.Encode(), None) self.assertEqual(IvrsParserTest.dte_f0h_2.Type, IVRS_TABLE.DEVICE_TABLE_ENTRY.DTE_TYPE.ACPI) self.assertEqual(IvrsParserTest.dte_f0h_2.DeviceID, 0x1111) self.assertEqual(IvrsParserTest.dte_f0h_2.DTESetting, 0xF6) - self.assertEqual(IvrsParserTest.dte_f0h_2.HID, b'FAKE0000') - self.assertEqual(IvrsParserTest.dte_f0h_2.CID, b'COMP0000') + self.assertEqual(IvrsParserTest.dte_f0h_2.HID, b"FAKE0000") + self.assertEqual(IvrsParserTest.dte_f0h_2.CID, b"COMP0000") self.assertEqual(IvrsParserTest.dte_f0h_2.UIDFormat, 0x02) self.assertEqual(IvrsParserTest.dte_f0h_2.UIDLength, 0x09) - self.assertEqual(IvrsParserTest.dte_f0h_2.UID, b'\\_SB.FUR0') + self.assertEqual(IvrsParserTest.dte_f0h_2.UID, b"\\_SB.FUR0") def test_ivrs_parser_ivhd_10h(self): # I/O Virtualization Hardware Definition (IVHD) Type 10h header - ivhd_t_10h = bytes([0x10, # Type - 0x90, # Flags - 0x18, 0x00, # Length - 0x02, 0x00, # DeviceID - 0x40, 0x00, # Capability offset - 0xEF, 0xBE, 0xAD, 0xDE, 0x0D, 0xF0, 0xED, 0xFE, # IOMMU base address - 0x00, 0x00, # PCI Segment Group - 0x00, 0x00, # IOMMU info - 0xBE, 0xBA, 0xAD, 0xAB]) # IOMMU Feature Reporting + ivhd_t_10h = bytes( + [ + 0x10, # Type + 0x90, # Flags + 0x18, + 0x00, # Length + 0x02, + 0x00, # DeviceID + 0x40, + 0x00, # Capability offset + 0xEF, + 0xBE, + 0xAD, + 0xDE, + 0x0D, + 0xF0, + 0xED, + 0xFE, # IOMMU base address + 0x00, + 0x00, # PCI Segment Group + 0x00, + 0x00, # IOMMU info + 0xBE, + 0xBA, + 0xAD, + 0xAB, + ] + ) # IOMMU Feature Reporting IvrsParserTest.ivhd_10h = IVRS_TABLE.IVHD_STRUCT(ivhd_t_10h) self.assertNotEqual(IvrsParserTest.ivhd_10h.Encode(), None) @@ -208,17 +304,50 @@ def test_ivrs_parser_ivhd_10h(self): def test_ivrs_parser_ivhd_11h(self): # I/O Virtualization Hardware Definition (IVHD) Type 11h header - ivhd_t_11h = bytes([0x11, # Type - 0x90, # Flags - 0x28, 0x00, # Length - 0x02, 0x00, # DeviceID - 0x40, 0x00, # Capability offset - 0xEF, 0xBE, 0xAD, 0xDE, 0x0D, 0xF0, 0xED, 0xFE, # IOMMU base address - 0x00, 0x00, # PCI Segment Group - 0x00, 0x00, # IOMMU info - 0xBE, 0xBA, 0xAD, 0xAB, # IOMMU Attributes - 0xDA, 0x4A, 0x29, 0x22, 0xEF, 0x77, 0x4F, 0x00, # EFR Register Image - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) # Reserved + ivhd_t_11h = bytes( + [ + 0x11, # Type + 0x90, # Flags + 0x28, + 0x00, # Length + 0x02, + 0x00, # DeviceID + 0x40, + 0x00, # Capability offset + 0xEF, + 0xBE, + 0xAD, + 0xDE, + 0x0D, + 0xF0, + 0xED, + 0xFE, # IOMMU base address + 0x00, + 0x00, # PCI Segment Group + 0x00, + 0x00, # IOMMU info + 0xBE, + 0xBA, + 0xAD, + 0xAB, # IOMMU Attributes + 0xDA, + 0x4A, + 0x29, + 0x22, + 0xEF, + 0x77, + 0x4F, + 0x00, # EFR Register Image + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ] + ) # Reserved IvrsParserTest.ivhd_11h = IVRS_TABLE.IVHD_STRUCT(ivhd_t_11h) self.assertNotEqual(IvrsParserTest.ivhd_11h.Encode(), None) @@ -235,17 +364,50 @@ def test_ivrs_parser_ivhd_11h(self): def test_ivrs_parser_ivhd_40h(self): # I/O Virtualization Hardware Definition (IVHD) Type 40h header - ivhd_t_40h = bytes([0x40, # Type - 0x90, # Flags - 0x28, 0x00, # Length - 0x02, 0x00, # DeviceID - 0x40, 0x00, # Capability offset - 0xEF, 0xBE, 0xAD, 0xDE, 0x0D, 0xF0, 0xED, 0xFE, # IOMMU base address - 0x00, 0x00, # PCI Segment Group - 0x00, 0x00, # IOMMU info - 0xBE, 0xBA, 0xAD, 0xAB, # IOMMU Attributes - 0xDA, 0x4A, 0x29, 0x22, 0xEF, 0x77, 0x4F, 0x00, # EFR Register Image - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) # Reserved + ivhd_t_40h = bytes( + [ + 0x40, # Type + 0x90, # Flags + 0x28, + 0x00, # Length + 0x02, + 0x00, # DeviceID + 0x40, + 0x00, # Capability offset + 0xEF, + 0xBE, + 0xAD, + 0xDE, + 0x0D, + 0xF0, + 0xED, + 0xFE, # IOMMU base address + 0x00, + 0x00, # PCI Segment Group + 0x00, + 0x00, # IOMMU info + 0xBE, + 0xBA, + 0xAD, + 0xAB, # IOMMU Attributes + 0xDA, + 0x4A, + 0x29, + 0x22, + 0xEF, + 0x77, + 0x4F, + 0x00, # EFR Register Image + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ] + ) # Reserved IvrsParserTest.ivhd_40h = IVRS_TABLE.IVHD_STRUCT(ivhd_t_40h) self.assertNotEqual(IvrsParserTest.ivhd_40h.Encode(), None) @@ -262,14 +424,42 @@ def test_ivrs_parser_ivhd_40h(self): def test_ivrs_parser_ivmd_20h(self): # IVMD Types 20h Format - ivmd_t_20h = bytes([0x20, # Type - 0x08, # Flags - 0x20, 0x00, # Length - 0x00, 0x00, # DeviceID - 0x00, 0x00, # Auxiliary data - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Reserved - 0xEF, 0xBE, 0xAD, 0xDE, 0x0D, 0xF0, 0xED, 0xFE, # IVMD start address - 0x00, 0xAD, 0xBB, 0xDA, 0xDE, 0xC0, 0x05, 0xB1]) # IVMD memory block length + ivmd_t_20h = bytes( + [ + 0x20, # Type + 0x08, # Flags + 0x20, + 0x00, # Length + 0x00, + 0x00, # DeviceID + 0x00, + 0x00, # Auxiliary data + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, # Reserved + 0xEF, + 0xBE, + 0xAD, + 0xDE, + 0x0D, + 0xF0, + 0xED, + 0xFE, # IVMD start address + 0x00, + 0xAD, + 0xBB, + 0xDA, + 0xDE, + 0xC0, + 0x05, + 0xB1, + ] + ) # IVMD memory block length IvrsParserTest.ivmd_20h = IVRS_TABLE.IVMD_STRUCT(ivmd_t_20h) self.assertNotEqual(IvrsParserTest.ivmd_20h.Encode(), None) @@ -284,14 +474,42 @@ def test_ivrs_parser_ivmd_20h(self): def test_ivrs_parser_ivmd_21h(self): # IVMD Types 21h Format - ivmd_t_21h = bytes([0x21, # Type - 0x08, # Flags - 0x20, 0x00, # Length - 0x00, 0x00, # DeviceID - 0x00, 0x00, # Auxiliary data - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Reserved - 0xEF, 0xBE, 0xAD, 0xDE, 0x0D, 0xF0, 0xED, 0xFE, # IVMD start address - 0x00, 0xAD, 0xBB, 0xDA, 0xDE, 0xC0, 0x05, 0xB1]) # IVMD memory block length + ivmd_t_21h = bytes( + [ + 0x21, # Type + 0x08, # Flags + 0x20, + 0x00, # Length + 0x00, + 0x00, # DeviceID + 0x00, + 0x00, # Auxiliary data + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, # Reserved + 0xEF, + 0xBE, + 0xAD, + 0xDE, + 0x0D, + 0xF0, + 0xED, + 0xFE, # IVMD start address + 0x00, + 0xAD, + 0xBB, + 0xDA, + 0xDE, + 0xC0, + 0x05, + 0xB1, + ] + ) # IVMD memory block length IvrsParserTest.ivmd_21h = IVRS_TABLE.IVMD_STRUCT(ivmd_t_21h) self.assertNotEqual(IvrsParserTest.ivmd_21h.Encode(), None) @@ -306,14 +524,42 @@ def test_ivrs_parser_ivmd_21h(self): def test_ivrs_parser_ivmd_22h(self): # IVMD Types 22h Format - ivmd_t_22h = bytes([0x22, # Type - 0x08, # Flags - 0x20, 0x00, # Length - 0x00, 0x00, # DeviceID - 0x00, 0x00, # Auxiliary data - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Reserved - 0xEF, 0xBE, 0xAD, 0xDE, 0x0D, 0xF0, 0xED, 0xFE, # IVMD start address - 0x00, 0xAD, 0xBB, 0xDA, 0xDE, 0xC0, 0x05, 0xB1]) # IVMD memory block length + ivmd_t_22h = bytes( + [ + 0x22, # Type + 0x08, # Flags + 0x20, + 0x00, # Length + 0x00, + 0x00, # DeviceID + 0x00, + 0x00, # Auxiliary data + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, # Reserved + 0xEF, + 0xBE, + 0xAD, + 0xDE, + 0x0D, + 0xF0, + 0xED, + 0xFE, # IVMD start address + 0x00, + 0xAD, + 0xBB, + 0xDA, + 0xDE, + 0xC0, + 0x05, + 0xB1, + ] + ) # IVMD memory block length IvrsParserTest.ivmd_22h = IVRS_TABLE.IVMD_STRUCT(ivmd_t_22h) self.assertNotEqual(IvrsParserTest.ivmd_22h.Encode(), None) @@ -327,29 +573,70 @@ def test_ivrs_parser_ivmd_22h(self): self.assertEqual(IvrsParserTest.ivmd_22h.IVMDMemoryBlockLength, 0xB105C0DEDABBAD00) def test_ivrs_parser_ivrs_empty(self): - ivrs_header = bytes([0x49, 0x56, 0x52, 0x53, # Signature: IVRS - 0x30, 0x00, 0x00, 0x00, # Length - 0x02, # Revision - 0x9C, # Checksum - 0x41, 0x4D, 0x44, 0x20, 0x20, 0x20, # OEM ID: 'AMD ' - 0x41, 0x4D, 0x44, 0x20, 0x49, 0x56, 0x52, 0x53, # OEM Table ID: 'AMD IVRS' - 0x01, 0x00, 0x00, 0x00, # OEM Revision - 0x41, 0x4D, 0x44, 0x20, # CreatorID: 'AMD ' - 0x00, 0x00, 0x00, 0x00, # Creator revision - 0x43, 0x30, 0x20, 0x00, # IVinfo - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) # Reserved: 0 + ivrs_header = bytes( + [ + 0x49, + 0x56, + 0x52, + 0x53, # Signature: IVRS + 0x30, + 0x00, + 0x00, + 0x00, # Length + 0x02, # Revision + 0x9C, # Checksum + 0x41, + 0x4D, + 0x44, + 0x20, + 0x20, + 0x20, # OEM ID: 'AMD ' + 0x41, + 0x4D, + 0x44, + 0x20, + 0x49, + 0x56, + 0x52, + 0x53, # OEM Table ID: 'AMD IVRS' + 0x01, + 0x00, + 0x00, + 0x00, # OEM Revision + 0x41, + 0x4D, + 0x44, + 0x20, # CreatorID: 'AMD ' + 0x00, + 0x00, + 0x00, + 0x00, # Creator revision + 0x43, + 0x30, + 0x20, + 0x00, # IVinfo + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ] + ) # Reserved: 0 IvrsParserTest.ivrs = IVRS_TABLE(ivrs_header) self.assertNotEqual(IvrsParserTest.ivrs.Encode(), None) - self.assertEqual(IvrsParserTest.ivrs.acpi_header.Signature, b'IVRS') + self.assertEqual(IvrsParserTest.ivrs.acpi_header.Signature, b"IVRS") self.assertEqual(IvrsParserTest.ivrs.acpi_header.Length, 0x30) self.assertEqual(IvrsParserTest.ivrs.acpi_header.Revision, 0x02) self.assertEqual(IvrsParserTest.ivrs.acpi_header.Checksum, 0x9C) - self.assertEqual(IvrsParserTest.ivrs.acpi_header.OEMID, b'AMD ') - self.assertEqual(IvrsParserTest.ivrs.acpi_header.OEMTableID, b'AMD IVRS') + self.assertEqual(IvrsParserTest.ivrs.acpi_header.OEMID, b"AMD ") + self.assertEqual(IvrsParserTest.ivrs.acpi_header.OEMTableID, b"AMD IVRS") self.assertEqual(IvrsParserTest.ivrs.acpi_header.OEMRevision, 1) - self.assertEqual(IvrsParserTest.ivrs.acpi_header.CreatorID, b'AMD ') + self.assertEqual(IvrsParserTest.ivrs.acpi_header.CreatorID, b"AMD ") self.assertEqual(IvrsParserTest.ivrs.acpi_header.CreatorRevision, 0) self.assertEqual(IvrsParserTest.ivrs.acpi_header.IVinfo, 0x00203043) self.assertEqual(IvrsParserTest.ivrs.acpi_header.Reserved, 0) @@ -386,5 +673,5 @@ def test_ivrs_parser_ivrs_full(self): self.assertEqual(ivrs2.Encode(), ivrs_byte) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests.unit/parsers/test_override_parser.py b/tests.unit/parsers/test_override_parser.py index 22f88756..7fa13d5e 100644 --- a/tests.unit/parsers/test_override_parser.py +++ b/tests.unit/parsers/test_override_parser.py @@ -12,9 +12,13 @@ from edk2toollib.uefi.edk2.parsers.override_parser import OverrideParser -SAMPLE_DATA_SINGLE_OVERRIDE = """#Override : 00000001 | My/Path/1 | 4e367990b327501d1ea6fbee4002f9c8 | 2018-11-27T22-36-30""" # noqa: E501 +SAMPLE_DATA_SINGLE_OVERRIDE = ( + """#Override : 00000001 | My/Path/1 | 4e367990b327501d1ea6fbee4002f9c8 | 2018-11-27T22-36-30""" # noqa: E501 +) -SAMPLE_DATA_BAD_VERSION = """#Override : 0000000X | My/Path/1 | 4e367990b327501d1ea6fbee4002f9c8 | 2018-11-27T22-36-30""" # noqa: E501 +SAMPLE_DATA_BAD_VERSION = ( + """#Override : 0000000X | My/Path/1 | 4e367990b327501d1ea6fbee4002f9c8 | 2018-11-27T22-36-30""" # noqa: E501 +) SAMPLE_DATA_BAD_DATE = """#Override : 00000001 | My/Path/1 | 4e367990b327501d1ea6fbee4002f9c8 | NOTADATE""" SAMPLE_DATA_TRIPLE_OVERRIDE = """ @@ -69,7 +73,6 @@ class TestOverrideParser(unittest.TestCase): - def test_no_inputs_raises_error(self): with self.assertRaises(ValueError): OverrideParser() @@ -90,12 +93,12 @@ def test_single_override_is_parsed(self): self.assertEqual(len(parser.override_lines), 1) self.assertEqual(len(parser.overrides), 1) - self.assertEqual(parser.overrides[0]['version'], 1) - self.assertEqual(parser.overrides[0]['original_path'].upper(), os.path.normpath('MY/PATH/1')) - self.assertEqual(parser.overrides[0]['current_hash'].upper(), '4E367990B327501D1EA6FBEE4002F9C8') - self.assertEqual(parser.overrides[0]['datetime'].year, 2018) - self.assertEqual(parser.overrides[0]['datetime'].month, 11) - self.assertEqual(parser.overrides[0]['datetime'].day, 27) + self.assertEqual(parser.overrides[0]["version"], 1) + self.assertEqual(parser.overrides[0]["original_path"].upper(), os.path.normpath("MY/PATH/1")) + self.assertEqual(parser.overrides[0]["current_hash"].upper(), "4E367990B327501D1EA6FBEE4002F9C8") + self.assertEqual(parser.overrides[0]["datetime"].year, 2018) + self.assertEqual(parser.overrides[0]["datetime"].month, 11) + self.assertEqual(parser.overrides[0]["datetime"].day, 27) def test_real_world_override_is_parsed(self): parser = OverrideParser(inf_contents=SAMPLE_DATA_REAL_WORLD) @@ -103,13 +106,15 @@ def test_real_world_override_is_parsed(self): self.assertEqual(len(parser.override_lines), 1) self.assertEqual(len(parser.overrides), 1) - self.assertEqual(parser.overrides[0]['version'], 1) - self.assertEqual(parser.overrides[0]['original_path'], - os.path.normpath('MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf')) - self.assertEqual(parser.overrides[0]['current_hash'].upper(), '2EBA0BC48B8AB3B1399C26800D057102') - self.assertEqual(parser.overrides[0]['datetime'].year, 2018) - self.assertEqual(parser.overrides[0]['datetime'].month, 10) - self.assertEqual(parser.overrides[0]['datetime'].day, 5) + self.assertEqual(parser.overrides[0]["version"], 1) + self.assertEqual( + parser.overrides[0]["original_path"], + os.path.normpath("MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf"), + ) + self.assertEqual(parser.overrides[0]["current_hash"].upper(), "2EBA0BC48B8AB3B1399C26800D057102") + self.assertEqual(parser.overrides[0]["datetime"].year, 2018) + self.assertEqual(parser.overrides[0]["datetime"].month, 10) + self.assertEqual(parser.overrides[0]["datetime"].day, 5) def test_triple_override_is_parsed(self): parser = OverrideParser(inf_contents=SAMPLE_DATA_TRIPLE_OVERRIDE) @@ -117,12 +122,12 @@ def test_triple_override_is_parsed(self): self.assertEqual(len(parser.override_lines), 3) self.assertEqual(len(parser.overrides), 3) - self.assertEqual(parser.overrides[0]['version'], 1) - self.assertEqual(parser.overrides[0]['current_hash'].upper(), '4E367990B327501D1EA6FBEE4002F9C8') - self.assertEqual(parser.overrides[1]['version'], 1) - self.assertEqual(parser.overrides[1]['current_hash'].upper(), '4E367990B327501D1EA6FBEE4002F9C8') - self.assertEqual(parser.overrides[2]['version'], 1) - self.assertEqual(parser.overrides[2]['current_hash'].upper(), '4E367990B327501D1EA6FBEE4002F9C8') + self.assertEqual(parser.overrides[0]["version"], 1) + self.assertEqual(parser.overrides[0]["current_hash"].upper(), "4E367990B327501D1EA6FBEE4002F9C8") + self.assertEqual(parser.overrides[1]["version"], 1) + self.assertEqual(parser.overrides[1]["current_hash"].upper(), "4E367990B327501D1EA6FBEE4002F9C8") + self.assertEqual(parser.overrides[2]["version"], 1) + self.assertEqual(parser.overrides[2]["current_hash"].upper(), "4E367990B327501D1EA6FBEE4002F9C8") def test_mixed_case_override_is_parsed(self): parser = OverrideParser(inf_contents=SAMPLE_DATA_MIXED_CASE_OVERRIDE) @@ -130,12 +135,12 @@ def test_mixed_case_override_is_parsed(self): self.assertEqual(len(parser.override_lines), 3) self.assertEqual(len(parser.overrides), 3) - self.assertEqual(parser.overrides[0]['version'], 1) - self.assertEqual(parser.overrides[0]['current_hash'].upper(), '4E367990B327501D1EA6FBEE4002F9C8') - self.assertEqual(parser.overrides[1]['version'], 1) - self.assertEqual(parser.overrides[1]['current_hash'].upper(), '4E367990B327501D1EA6FBEE4002F9C8') - self.assertEqual(parser.overrides[2]['version'], 1) - self.assertEqual(parser.overrides[2]['current_hash'].upper(), '4E367990B327501D1EA6FBEE4002F9C8') + self.assertEqual(parser.overrides[0]["version"], 1) + self.assertEqual(parser.overrides[0]["current_hash"].upper(), "4E367990B327501D1EA6FBEE4002F9C8") + self.assertEqual(parser.overrides[1]["version"], 1) + self.assertEqual(parser.overrides[1]["current_hash"].upper(), "4E367990B327501D1EA6FBEE4002F9C8") + self.assertEqual(parser.overrides[2]["version"], 1) + self.assertEqual(parser.overrides[2]["current_hash"].upper(), "4E367990B327501D1EA6FBEE4002F9C8") def test_parses_all_versions(self): # TODO: Fill out this test if it's ever needed. diff --git a/tests.unit/test_ansi_handler.py b/tests.unit/test_ansi_handler.py index 20f4f0d4..5529c381 100644 --- a/tests.unit/test_ansi_handler.py +++ b/tests.unit/test_ansi_handler.py @@ -17,24 +17,64 @@ class AnsiHandlerTest(unittest.TestCase): - # we are mainly looking for exception to be thrown - record = logging.makeLogRecord({"name": "", "level": logging.CRITICAL, "levelno": logging.CRITICAL, - "levelname": "CRITICAL", "path": "test_path", "lineno": 0, - "msg": "Test message"}) - record2 = logging.makeLogRecord({"name": "", "level": logging.INFO, "levelno": logging.INFO, - "levelname": "INFO", "path": "test_path", "lineno": 0, - "msg": "Test message"}) - record3 = logging.makeLogRecord({"name": "", "level": logging.ERROR, "levelno": logging.ERROR, - "levelname": "ERROR", "path": "test_path", "lineno": 0, - "msg": ['Logging', 'A', 'List']}) - record4 = logging.makeLogRecord({"name": "", "level": logging.ERROR, "levelno": logging.ERROR, - "levelname": "ERROR", "path": "test_path", "lineno": 0, - "msg": ('Logging', 'A', 'Tuple')}) - record5 = logging.makeLogRecord({"name": "", "level": logging.ERROR, "levelno": logging.ERROR, - "levelname": "ERROR", "path": "test_path", "lineno": 0, - "msg": "Testing This Works: %s", "args": ("Test",)}) + record = logging.makeLogRecord( + { + "name": "", + "level": logging.CRITICAL, + "levelno": logging.CRITICAL, + "levelname": "CRITICAL", + "path": "test_path", + "lineno": 0, + "msg": "Test message", + } + ) + record2 = logging.makeLogRecord( + { + "name": "", + "level": logging.INFO, + "levelno": logging.INFO, + "levelname": "INFO", + "path": "test_path", + "lineno": 0, + "msg": "Test message", + } + ) + record3 = logging.makeLogRecord( + { + "name": "", + "level": logging.ERROR, + "levelno": logging.ERROR, + "levelname": "ERROR", + "path": "test_path", + "lineno": 0, + "msg": ["Logging", "A", "List"], + } + ) + record4 = logging.makeLogRecord( + { + "name": "", + "level": logging.ERROR, + "levelno": logging.ERROR, + "levelname": "ERROR", + "path": "test_path", + "lineno": 0, + "msg": ("Logging", "A", "Tuple"), + } + ) + record5 = logging.makeLogRecord( + { + "name": "", + "level": logging.ERROR, + "levelno": logging.ERROR, + "levelname": "ERROR", + "path": "test_path", + "lineno": 0, + "msg": "Testing This Works: %s", + "args": ("Test",), + } + ) def test_colored_formatter_init(self): formatter = ColoredFormatter("%(levelname)s - %(message)s") @@ -46,7 +86,7 @@ def test_colored_formatter_to_output_ansi(self): output = formatter.format(AnsiHandlerTest.record) self.assertNotEqual(output, None) - CSI = '\033[' + CSI = "\033[" self.assertGreater(len(output), 0, "We should have some output") self.assertFalse((CSI not in output), "There was supposed to be a ANSI control code in that %s" % output) @@ -61,7 +101,7 @@ def test_color_handler_to_strip_ansi(self): handler.emit(AnsiHandlerTest.record) handler.flush() - CSI = '\033[' + CSI = "\033[" # check for ANSI escape code in stream stream.seek(0) @@ -81,7 +121,7 @@ def test_color_handler_not_strip_ansi(self): handler.emit(AnsiHandlerTest.record2) handler.flush() - CSI = '\033[' + CSI = "\033[" found_csi = False stream.seek(0) @@ -107,7 +147,7 @@ def test_ansi_handler_with_list(self): stream.seek(0) lines = stream.readlines() - CSI = '\033[31m' # Red - CSI2 = '\033[39m' # Reset + CSI = "\033[31m" # Red + CSI2 = "\033[39m" # Reset for line in lines: assert CSI in line and CSI2 in line diff --git a/tests.unit/test_authenticated_variables_structure_support.py b/tests.unit/test_authenticated_variables_structure_support.py index c9474c2a..ff5598f4 100644 --- a/tests.unit/test_authenticated_variables_structure_support.py +++ b/tests.unit/test_authenticated_variables_structure_support.py @@ -48,8 +48,7 @@ def sha256_esl_builder(initList: []): for entry in initList: (hashStr, ownerGuidStr) = entry hashBytes = bytes.fromhex(hashStr) - esl.AddSignatureData(EfiSignatureDataEfiCertSha256(digest=hashBytes, - sigowner=uuid.UUID(ownerGuidStr))) + esl.AddSignatureData(EfiSignatureDataEfiCertSha256(digest=hashBytes, sigowner=uuid.UUID(ownerGuidStr))) return esl @@ -64,19 +63,18 @@ def x509_esl_builder(initList: []): """ listSize = len(initList) - if (listSize > 1): + if listSize > 1: raise Exception("initList length > 1, unsupported by type") esl = EfiSignatureList(typeguid=EfiSignatureDataFactory.EFI_CERT_X509_GUID) - if (listSize == 0): + if listSize == 0: esl.AddSignatureHeader(SigHeader=None, SigSize=0) else: (certHexStr, ownerGuidStr) = initList[0] certBytes = bytes.fromhex(certHexStr) esl.AddSignatureHeader(SigHeader=None, SigSize=EfiSignatureDataEfiCertX509.STATIC_STRUCT_SIZE + len(certBytes)) - esl.AddSignatureData(EfiSignatureDataEfiCertX509(cert=certBytes, - sigowner=uuid.UUID(ownerGuidStr))) + esl.AddSignatureData(EfiSignatureDataEfiCertX509(cert=certBytes, sigowner=uuid.UUID(ownerGuidStr))) return esl @@ -95,101 +93,99 @@ def basicEfiSignatureDatabase(): (HASHSTR[1], owner), (HASHSTR[2], owner), (HASHSTR[1], owner), - (HASHSTR[2], owner) + (HASHSTR[2], owner), ] hashes = sha256_esl_builder(hash_esl_input) - esl_list = [ - cert, hashes - ] + esl_list = [cert, hashes] return EfiSignatureDatabase(esl_list=esl_list) def BootHoleData(): """Returns a tuple of the (rawData, expectedDupes, expectedCanonical) for the BootHole dbx generated by EDK2""" - owner = '77fa9abd-0359-4d32-bd60-28f4e78f784b' + owner = "77fa9abd-0359-4d32-bd60-28f4e78f784b" # First prepare EfiSignatureDatabase that is unsorted, unmerged, and contains duplicates original_hashes = [ - ('80B4D96931BF0D02FD91A61E19D14F1DA452E66DB2408CA8604D411F92659F0A', owner), - ('F52F83A3FA9CFBD6920F722824DBE4034534D25B8507246B3B957DAC6E1BCE7A', owner), - ('C5D9D8A186E2C82D09AFAA2A6F7F2E73870D3E64F72C4E08EF67796A840F0FBD', owner), - ('363384D14D1F2E0B7815626484C459AD57A318EF4396266048D058C5A19BBF76', owner), - ('1AEC84B84B6C65A51220A9BE7181965230210D62D6D33C48999C6B295A2B0A06', owner), - ('E6CA68E94146629AF03F69C2F86E6BEF62F930B37C6FBCC878B78DF98C0334E5', owner), - ('C3A99A460DA464A057C3586D83CEF5F4AE08B7103979ED8932742DF0ED530C66', owner), - ('58FB941AEF95A25943B3FB5F2510A0DF3FE44C58C95E0AB80487297568AB9771', owner), - ('5391C3A2FB112102A6AA1EDC25AE77E19F5D6F09CD09EEB2509922BFCD5992EA', owner), - ('D626157E1D6A718BC124AB8DA27CBB65072CA03A7B6B257DBDCBBD60F65EF3D1', owner), - ('D063EC28F67EBA53F1642DBF7DFF33C6A32ADD869F6013FE162E2C32F1CBE56D', owner), - ('29C6EB52B43C3AA18B2CD8ED6EA8607CEF3CFAE1BAFE1165755CF2E614844A44', owner), - ('90FBE70E69D633408D3E170C6832DBB2D209E0272527DFB63D49D29572A6F44C', owner), - ('075EEA060589548BA060B2FEED10DA3C20C7FE9B17CD026B94E8A683B8115238', owner), - ('07E6C6A858646FB1EFC67903FE28B116011F2367FE92E6BE2B36999EFF39D09E', owner), - ('09DF5F4E511208EC78B96D12D08125FDB603868DE39F6F72927852599B659C26', owner), - ('0BBB4392DAAC7AB89B30A4AC657531B97BFAAB04F90B0DAFE5F9B6EB90A06374', owner), - ('0C189339762DF336AB3DD006A463DF715A39CFB0F492465C600E6C6BD7BD898C', owner), - ('0D0DBECA6F29ECA06F331A7D72E4884B12097FB348983A2A14A0D73F4F10140F', owner), - ('0DC9F3FB99962148C3CA833632758D3ED4FC8D0B0007B95B31E6528F2ACD5BFC', owner), - ('106FACEACFECFD4E303B74F480A08098E2D0802B936F8EC774CE21F31686689C', owner), - ('174E3A0B5B43C6A607BBD3404F05341E3DCF396267CE94F8B50E2E23A9DA920C', owner), - ('18333429FF0562ED9F97033E1148DCEEE52DBE2E496D5410B5CFD6C864D2D10F', owner), - ('2B99CF26422E92FE365FBF4BC30D27086C9EE14B7A6FFF44FB2F6B9001699939', owner), - ('2BBF2CA7B8F1D91F27EE52B6FB2A5DD049B85A2B9B529C5D6662068104B055F8', owner), - ('2C73D93325BA6DCBE589D4A4C63C5B935559EF92FBF050ED50C4E2085206F17D', owner), - ('2E70916786A6F773511FA7181FAB0F1D70B557C6322EA923B2A8D3B92B51AF7D', owner), - ('306628FA5477305728BA4A467DE7D0387A54F569D3769FCE5E75EC89D28D1593', owner), - ('3608EDBAF5AD0F41A414A1777ABF2FAF5E670334675EC3995E6935829E0CAAD2', owner), - ('3841D221368D1583D75C0A02E62160394D6C4E0A6760B6F607B90362BC855B02', owner), - ('3FCE9B9FDF3EF09D5452B0F95EE481C2B7F06D743A737971558E70136ACE3E73', owner), - ('4397DACA839E7F63077CB50C92DF43BC2D2FB2A8F59F26FC7A0E4BD4D9751692', owner), - ('47CC086127E2069A86E03A6BEF2CD410F8C55A6D6BDB362168C31B2CE32A5ADF', owner), - ('518831FE7382B514D03E15C621228B8AB65479BD0CBFA3C5C1D0F48D9C306135', owner), - ('5AE949EA8855EB93E439DBC65BDA2E42852C2FDF6789FA146736E3C3410F2B5C', owner), - ('6B1D138078E4418AA68DEB7BB35E066092CF479EEB8CE4CD12E7D072CCB42F66', owner), - ('6C8854478DD559E29351B826C06CB8BFEF2B94AD3538358772D193F82ED1CA11', owner), - ('6F1428FF71C9DB0ED5AF1F2E7BBFCBAB647CC265DDF5B293CDB626F50A3A785E', owner), - ('71F2906FD222497E54A34662AB2497FCC81020770FF51368E9E3D9BFCBFD6375', owner), - ('726B3EB654046A30F3F83D9B96CE03F670E9A806D1708A0371E62DC49D2C23C1', owner), - ('72E0BD1867CF5D9D56AB158ADF3BDDBC82BF32A8D8AA1D8C5E2F6DF29428D6D8', owner), - ('7827AF99362CFAF0717DADE4B1BFE0438AD171C15ADDC248B75BF8CAA44BB2C5', owner), - ('81A8B965BB84D3876B9429A95481CC955318CFAA1412D808C8A33BFD33FFF0E4', owner), - ('82DB3BCEB4F60843CE9D97C3D187CD9B5941CD3DE8100E586F2BDA5637575F67', owner), - ('895A9785F617CA1D7ED44FC1A1470B71F3F1223862D9FF9DCC3AE2DF92163DAF', owner), - ('8AD64859F195B5F58DAFAA940B6A6167ACD67A886E8F469364177221C55945B9', owner), - ('8BF434B49E00CCF71502A2CD900865CB01EC3B3DA03C35BE505FDF7BD563F521', owner), - ('8D8EA289CFE70A1C07AB7365CB28EE51EDD33CF2506DE888FBADD60EBF80481C', owner), - ('9998D363C491BE16BD74BA10B94D9291001611736FDCA643A36664BC0F315A42', owner), - ('9E4A69173161682E55FDE8FEF560EB88EC1FFEDCAF04001F66C0CAF707B2B734', owner), - ('A6B5151F3655D3A2AF0D472759796BE4A4200E5495A7D869754C4848857408A7', owner), - ('A7F32F508D4EB0FEAD9A087EF94ED1BA0AEC5DE6F7EF6FF0A62B93BEDF5D458D', owner), - ('AD6826E1946D26D3EAF3685C88D97D85DE3B4DCB3D0EE2AE81C70560D13C5720', owner), - ('AEEBAE3151271273ED95AA2E671139ED31A98567303A332298F83709A9D55AA1', owner), - ('AFE2030AFB7D2CDA13F9FA333A02E34F6751AFEC11B010DBCD441FDF4C4002B3', owner), - ('B54F1EE636631FAD68058D3B0937031AC1B90CCB17062A391CCA68AFDBE40D55', owner), - ('B8F078D983A24AC433216393883514CD932C33AF18E7DD70884C8235F4275736', owner), - ('B97A0889059C035FF1D54B6DB53B11B9766668D9F955247C028B2837D7A04CD9', owner), - ('BC87A668E81966489CB508EE805183C19E6ACD24CF17799CA062D2E384DA0EA7', owner), - ('C409BDAC4775ADD8DB92AA22B5B718FB8C94A1462C1FE9A416B95D8A3388C2FC', owner), - ('C617C1A8B1EE2A811C28B5A81B4C83D7C98B5B0C27281D610207EBE692C2967F', owner), - ('C90F336617B8E7F983975413C997F10B73EB267FD8A10CB9E3BDBFC667ABDB8B', owner), - ('CB6B858B40D3A098765815B592C1514A49604FAFD60819DA88D7A76E9778FEF7', owner), - ('CE3BFABE59D67CE8AC8DFD4A16F7C43EF9C224513FBC655957D735FA29F540CE', owner), - ('D8CBEB9735F5672B367E4F96CDC74969615D17074AE96C724D42CE0216F8F3FA', owner), - ('E92C22EB3B5642D65C1EC2CAF247D2594738EEBB7FB3841A44956F59E2B0D1FA', owner), - ('FDDD6E3D29EA84C7743DAD4A1BDBC700B5FEC1B391F932409086ACC71DD6DBD8', owner), - ('FE63A84F782CC9D3FCF2CCF9FC11FBD03760878758D26285ED12669BDC6E6D01', owner), - ('FECFB232D12E994B6D485D2C7167728AA5525984AD5CA61E7516221F079A1436', owner), - ('CA171D614A8D7E121C93948CD0FE55D39981F9D11AA96E03450A415227C2C65B', owner), - ('55B99B0DE53DBCFE485AA9C737CF3FB616EF3D91FAB599AA7CAB19EDA763B5BA', owner), - ('77DD190FA30D88FF5E3B011A0AE61E6209780C130B535ECB87E6F0888A0B6B2F', owner), - ('C83CB13922AD99F560744675DD37CC94DCAD5A1FCBA6472FEE341171D939E884', owner), - ('3B0287533E0CC3D0EC1AA823CBF0A941AAD8721579D1C499802DD1C3A636B8A9', owner), - ('939AEEF4F5FA51E23340C3F2E49048CE8872526AFDF752C3A7F3A3F2BC9F6049', owner), - ('64575BD912789A2E14AD56F6341F52AF6BF80CF94400785975E9F04E2D64D745', owner), - ('45C7C8AE750ACFBB48FC37527D6412DD644DAED8913CCD8A24C94D856967DF8E', owner) + ("80B4D96931BF0D02FD91A61E19D14F1DA452E66DB2408CA8604D411F92659F0A", owner), + ("F52F83A3FA9CFBD6920F722824DBE4034534D25B8507246B3B957DAC6E1BCE7A", owner), + ("C5D9D8A186E2C82D09AFAA2A6F7F2E73870D3E64F72C4E08EF67796A840F0FBD", owner), + ("363384D14D1F2E0B7815626484C459AD57A318EF4396266048D058C5A19BBF76", owner), + ("1AEC84B84B6C65A51220A9BE7181965230210D62D6D33C48999C6B295A2B0A06", owner), + ("E6CA68E94146629AF03F69C2F86E6BEF62F930B37C6FBCC878B78DF98C0334E5", owner), + ("C3A99A460DA464A057C3586D83CEF5F4AE08B7103979ED8932742DF0ED530C66", owner), + ("58FB941AEF95A25943B3FB5F2510A0DF3FE44C58C95E0AB80487297568AB9771", owner), + ("5391C3A2FB112102A6AA1EDC25AE77E19F5D6F09CD09EEB2509922BFCD5992EA", owner), + ("D626157E1D6A718BC124AB8DA27CBB65072CA03A7B6B257DBDCBBD60F65EF3D1", owner), + ("D063EC28F67EBA53F1642DBF7DFF33C6A32ADD869F6013FE162E2C32F1CBE56D", owner), + ("29C6EB52B43C3AA18B2CD8ED6EA8607CEF3CFAE1BAFE1165755CF2E614844A44", owner), + ("90FBE70E69D633408D3E170C6832DBB2D209E0272527DFB63D49D29572A6F44C", owner), + ("075EEA060589548BA060B2FEED10DA3C20C7FE9B17CD026B94E8A683B8115238", owner), + ("07E6C6A858646FB1EFC67903FE28B116011F2367FE92E6BE2B36999EFF39D09E", owner), + ("09DF5F4E511208EC78B96D12D08125FDB603868DE39F6F72927852599B659C26", owner), + ("0BBB4392DAAC7AB89B30A4AC657531B97BFAAB04F90B0DAFE5F9B6EB90A06374", owner), + ("0C189339762DF336AB3DD006A463DF715A39CFB0F492465C600E6C6BD7BD898C", owner), + ("0D0DBECA6F29ECA06F331A7D72E4884B12097FB348983A2A14A0D73F4F10140F", owner), + ("0DC9F3FB99962148C3CA833632758D3ED4FC8D0B0007B95B31E6528F2ACD5BFC", owner), + ("106FACEACFECFD4E303B74F480A08098E2D0802B936F8EC774CE21F31686689C", owner), + ("174E3A0B5B43C6A607BBD3404F05341E3DCF396267CE94F8B50E2E23A9DA920C", owner), + ("18333429FF0562ED9F97033E1148DCEEE52DBE2E496D5410B5CFD6C864D2D10F", owner), + ("2B99CF26422E92FE365FBF4BC30D27086C9EE14B7A6FFF44FB2F6B9001699939", owner), + ("2BBF2CA7B8F1D91F27EE52B6FB2A5DD049B85A2B9B529C5D6662068104B055F8", owner), + ("2C73D93325BA6DCBE589D4A4C63C5B935559EF92FBF050ED50C4E2085206F17D", owner), + ("2E70916786A6F773511FA7181FAB0F1D70B557C6322EA923B2A8D3B92B51AF7D", owner), + ("306628FA5477305728BA4A467DE7D0387A54F569D3769FCE5E75EC89D28D1593", owner), + ("3608EDBAF5AD0F41A414A1777ABF2FAF5E670334675EC3995E6935829E0CAAD2", owner), + ("3841D221368D1583D75C0A02E62160394D6C4E0A6760B6F607B90362BC855B02", owner), + ("3FCE9B9FDF3EF09D5452B0F95EE481C2B7F06D743A737971558E70136ACE3E73", owner), + ("4397DACA839E7F63077CB50C92DF43BC2D2FB2A8F59F26FC7A0E4BD4D9751692", owner), + ("47CC086127E2069A86E03A6BEF2CD410F8C55A6D6BDB362168C31B2CE32A5ADF", owner), + ("518831FE7382B514D03E15C621228B8AB65479BD0CBFA3C5C1D0F48D9C306135", owner), + ("5AE949EA8855EB93E439DBC65BDA2E42852C2FDF6789FA146736E3C3410F2B5C", owner), + ("6B1D138078E4418AA68DEB7BB35E066092CF479EEB8CE4CD12E7D072CCB42F66", owner), + ("6C8854478DD559E29351B826C06CB8BFEF2B94AD3538358772D193F82ED1CA11", owner), + ("6F1428FF71C9DB0ED5AF1F2E7BBFCBAB647CC265DDF5B293CDB626F50A3A785E", owner), + ("71F2906FD222497E54A34662AB2497FCC81020770FF51368E9E3D9BFCBFD6375", owner), + ("726B3EB654046A30F3F83D9B96CE03F670E9A806D1708A0371E62DC49D2C23C1", owner), + ("72E0BD1867CF5D9D56AB158ADF3BDDBC82BF32A8D8AA1D8C5E2F6DF29428D6D8", owner), + ("7827AF99362CFAF0717DADE4B1BFE0438AD171C15ADDC248B75BF8CAA44BB2C5", owner), + ("81A8B965BB84D3876B9429A95481CC955318CFAA1412D808C8A33BFD33FFF0E4", owner), + ("82DB3BCEB4F60843CE9D97C3D187CD9B5941CD3DE8100E586F2BDA5637575F67", owner), + ("895A9785F617CA1D7ED44FC1A1470B71F3F1223862D9FF9DCC3AE2DF92163DAF", owner), + ("8AD64859F195B5F58DAFAA940B6A6167ACD67A886E8F469364177221C55945B9", owner), + ("8BF434B49E00CCF71502A2CD900865CB01EC3B3DA03C35BE505FDF7BD563F521", owner), + ("8D8EA289CFE70A1C07AB7365CB28EE51EDD33CF2506DE888FBADD60EBF80481C", owner), + ("9998D363C491BE16BD74BA10B94D9291001611736FDCA643A36664BC0F315A42", owner), + ("9E4A69173161682E55FDE8FEF560EB88EC1FFEDCAF04001F66C0CAF707B2B734", owner), + ("A6B5151F3655D3A2AF0D472759796BE4A4200E5495A7D869754C4848857408A7", owner), + ("A7F32F508D4EB0FEAD9A087EF94ED1BA0AEC5DE6F7EF6FF0A62B93BEDF5D458D", owner), + ("AD6826E1946D26D3EAF3685C88D97D85DE3B4DCB3D0EE2AE81C70560D13C5720", owner), + ("AEEBAE3151271273ED95AA2E671139ED31A98567303A332298F83709A9D55AA1", owner), + ("AFE2030AFB7D2CDA13F9FA333A02E34F6751AFEC11B010DBCD441FDF4C4002B3", owner), + ("B54F1EE636631FAD68058D3B0937031AC1B90CCB17062A391CCA68AFDBE40D55", owner), + ("B8F078D983A24AC433216393883514CD932C33AF18E7DD70884C8235F4275736", owner), + ("B97A0889059C035FF1D54B6DB53B11B9766668D9F955247C028B2837D7A04CD9", owner), + ("BC87A668E81966489CB508EE805183C19E6ACD24CF17799CA062D2E384DA0EA7", owner), + ("C409BDAC4775ADD8DB92AA22B5B718FB8C94A1462C1FE9A416B95D8A3388C2FC", owner), + ("C617C1A8B1EE2A811C28B5A81B4C83D7C98B5B0C27281D610207EBE692C2967F", owner), + ("C90F336617B8E7F983975413C997F10B73EB267FD8A10CB9E3BDBFC667ABDB8B", owner), + ("CB6B858B40D3A098765815B592C1514A49604FAFD60819DA88D7A76E9778FEF7", owner), + ("CE3BFABE59D67CE8AC8DFD4A16F7C43EF9C224513FBC655957D735FA29F540CE", owner), + ("D8CBEB9735F5672B367E4F96CDC74969615D17074AE96C724D42CE0216F8F3FA", owner), + ("E92C22EB3B5642D65C1EC2CAF247D2594738EEBB7FB3841A44956F59E2B0D1FA", owner), + ("FDDD6E3D29EA84C7743DAD4A1BDBC700B5FEC1B391F932409086ACC71DD6DBD8", owner), + ("FE63A84F782CC9D3FCF2CCF9FC11FBD03760878758D26285ED12669BDC6E6D01", owner), + ("FECFB232D12E994B6D485D2C7167728AA5525984AD5CA61E7516221F079A1436", owner), + ("CA171D614A8D7E121C93948CD0FE55D39981F9D11AA96E03450A415227C2C65B", owner), + ("55B99B0DE53DBCFE485AA9C737CF3FB616EF3D91FAB599AA7CAB19EDA763B5BA", owner), + ("77DD190FA30D88FF5E3B011A0AE61E6209780C130B535ECB87E6F0888A0B6B2F", owner), + ("C83CB13922AD99F560744675DD37CC94DCAD5A1FCBA6472FEE341171D939E884", owner), + ("3B0287533E0CC3D0EC1AA823CBF0A941AAD8721579D1C499802DD1C3A636B8A9", owner), + ("939AEEF4F5FA51E23340C3F2E49048CE8872526AFDF752C3A7F3A3F2BC9F6049", owner), + ("64575BD912789A2E14AD56F6341F52AF6BF80CF94400785975E9F04E2D64D745", owner), + ("45C7C8AE750ACFBB48FC37527D6412DD644DAED8913CCD8A24C94D856967DF8E", owner), ] original_esl = sha256_esl_builder(original_hashes) @@ -200,167 +196,167 @@ def BootHoleData(): cert2_esl = x509_esl_builder(cert2) new_hashes = [ - ('81D8FB4C9E2E7A8225656B4B8273B7CBA4B03EF2E9EB20E0A0291624ECA1BA86', owner), - ('B92AF298DC08049B78C77492D6551B710CD72AADA3D77BE54609E43278EF6E4D', owner), - ('E19DAE83C02E6F281358D4EBD11D7723B4F5EA0E357907D5443DECC5F93C1E9D', owner), - ('39DBC2288EF44B5F95332CB777E31103E840DBA680634AA806F5C9B100061802', owner), - ('32F5940CA29DD812A2C145E6FC89646628FFCC7C7A42CAE512337D8D29C40BBD', owner), - ('10D45FCBA396AEF3153EE8F6ECAE58AFE8476A280A2026FC71F6217DCF49BA2F', owner), - ('4B8668A5D465BCDD9000AA8DFCFF42044FCBD0AECE32FC7011A83E9160E89F09', owner), - ('89F3D1F6E485C334CD059D0995E3CDFDC00571B1849854847A44DC5548E2DCFB', owner), - ('C9EC350406F26E559AFFB4030DE2EBDE5435054C35A998605B8FCF04972D8D55', owner), - ('B3E506340FBF6B5786973393079F24B66BA46507E35E911DB0362A2ACDE97049', owner), - ('9F1863ED5717C394B42EF10A6607B144A65BA11FB6579DF94B8EB2F0C4CD60C1', owner), - ('DD59AF56084406E38C63FBE0850F30A0CD1277462A2192590FB05BC259E61273', owner), - ('DBAF9E056D3D5B38B68553304ABC88827EBC00F80CB9C7E197CDBC5822CD316C', owner), - ('65F3C0A01B8402D362B9722E98F75E5E991E6C186E934F7B2B2E6BE6DEC800EC', owner), - ('5B248E913D71853D3DA5AEDD8D9A4BC57A917126573817FB5FCB2D86A2F1C886', owner), - ('2679650FE341F2CF1EA883460B3556AAAF77A70D6B8DC484C9301D1B746CF7B5', owner), - ('BB1DD16D530008636F232303A7A86F3DFF969F848815C0574B12C2D787FEC93F', owner), - ('0CE02100F67C7EF85F4EED368F02BF7092380A3C23CA91FD7F19430D94B00C19', owner), - ('95049F0E4137C790B0D2767195E56F73807D123ADCF8F6E7BF2D4D991D305F89', owner), - ('02E6216ACAEF6401401FA555ECBED940B1A5F2569AED92956137AE58482EF1B7', owner), - ('6EFEFE0B5B01478B7B944C10D3A8ACA2CCA4208888E2059F8A06CB5824D7BAB0', owner), - ('9D00AE4CD47A41C783DC48F342C076C2C16F3413F4D2DF50D181CA3BB5AD859D', owner), - ('D8D4E6DDF6E42D74A6A536EA62FD1217E4290B145C9E5C3695A31B42EFB5F5A4', owner), - ('F277AF4F9BDC918AE89FA35CC1B34E34984C04AE9765322C3CB049574D36509C', owner), - ('0DC24C75EB1AEF56B9F13AB9DE60E2ECA1C4510034E290BBB36CF60A549B234C', owner), - ('835881F2A5572D7059B5C8635018552892E945626F115FC9CA07ACF7BDE857A4', owner), - ('BADFF5E4F0FEA711701CA8FB22E4C43821E31E210CF52D1D4F74DD50F1D039BC', owner), - ('C452AB846073DF5ACE25CCA64D6B7A09D906308A1A65EB5240E3C4EBCAA9CC0C', owner), - ('F1863EC8B7F43F94AD14FB0B8B4A69497A8C65ECBC2A55E0BB420E772B8CDC91', owner), - ('7BC9CB5463CE0F011FB5085EB8BA77D1ACD283C43F4A57603CC113F22CEBC579', owner), - ('E800395DBE0E045781E8005178B4BAF5A257F06E159121A67C595F6AE22506FD', owner), - ('1CB4DCCAF2C812CFA7B4938E1371FE2B96910FE407216FD95428672D6C7E7316', owner), - ('3ECE27CBB3EC4438CCE523B927C4F05FDC5C593A3766DB984C5E437A3FF6A16B', owner), - ('68EE4632C7BE1C66C83E89DD93EAEE1294159ABF45B4C2C72D7DC7499AA2A043', owner), - ('E24B315A551671483D8B9073B32DE11B4DE1EB2EAB211AFD2D9C319FF55E08D0', owner), - ('E7C20B3AB481EC885501ECA5293781D84B5A1AC24F88266B5270E7ECB4AA2538', owner), - ('7EAC80A915C84CD4AFEC638904D94EB168A8557951A4D539B0713028552B6B8C', owner), - ('E7681F153121EA1E67F74BBCB0CDC5E502702C1B8CC55FB65D702DFBA948B5F4', owner), - ('DCCC3CE1C00EE4B0B10487D372A0FA47F5C26F57A359BE7B27801E144EACBAC4', owner), - ('0257FF710F2A16E489B37493C07604A7CDA96129D8A8FD68D2B6AF633904315D', owner), - ('3A91F0F9E5287FA2994C7D930B2C1A5EE14CE8E1C8304AE495ADC58CC4453C0C', owner), - ('495300790E6C9BF2510DABA59DB3D57E9D2B85D7D7640434EC75BAA3851C74E5', owner), - ('81A8B2C9751AEB1FABA7DBDE5EE9691DC0EAEE2A31C38B1491A8146756A6B770', owner), - ('8E53EFDC15F852CEE5A6E92931BC42E6163CD30FF649CCA7E87252C3A459960B', owner), - ('992D359AA7A5F789D268B94C11B9485A6B1CE64362B0EDB4441CCC187C39647B', owner), - ('9FA4D5023FD43ECAFF4200BA7E8D4353259D2B7E5E72B5096EFF8027D66D1043', owner), - ('D372C0D0F4FDC9F52E9E1F23FC56EE72414A17F350D0CEA6C26A35A6C3217A13', owner), - ('5C5805196A85E93789457017D4F9EB6828B97C41CB9BA6D3DC1FCC115F527A55', owner), - ('804E354C6368BB27A90FAE8E498A57052B293418259A019C4F53A2007254490F', owner), - ('03F64A29948A88BEFFDB035E0B09A7370CCF0CD9CE6BCF8E640C2107318FAB87', owner), - ('05D87E15713454616F5B0ED7849AB5C1712AB84F02349478EC2A38F970C01489', owner), - ('06EB5BADD26E4FAE65F9A42358DEEF7C18E52CC05FBB7FC76776E69D1B982A14', owner), - ('08BB2289E9E91B4D20FF3F1562516AB07E979B2C6CEFE2AB70C6DFC1199F8DA5', owner), - ('0928F0408BF725E61D67D87138A8EEBC52962D2847F16E3587163B160E41B6AD', owner), - ('09F98AA90F85198C0D73F89BA77E87EC6F596C491350FB8F8BBA80A62FBB914B', owner), - ('0A75EA0B1D70EAA4D3F374246DB54FC7B43E7F596A353309B9C36B4FD975725E', owner), - ('0C51D7906FC4931149765DA88682426B2CFE9E6AA4F27253EAB400111432E3A7', owner), - ('0FA3A29AD05130D7FE5BF4D2596563CDED1D874096AACC181069932A2E49519A', owner), - ('147730B42F11FE493FE902B6251E97CD2B6F34D36AF59330F11D02A42F940D07', owner), - ('148FE18F715A9FCFE1A444CE0FFF7F85869EB422330DC04B314C0F295D6DA79E', owner), - ('1B909115A8D473E51328A87823BD621CE655DFAE54FA2BFA72FDC0298611D6B8', owner), - ('1D8B58C1FDB8DA8B33CCEE1E5F973AF734D90EF317E33F5DB1573C2BA088A80C', owner), - ('1F179186EFDF5EF2DE018245BA0EAE8134868601BA0D35FF3D9865C1537CED93', owner), - ('270C84B29D86F16312B06AAAE4EBB8DFF8DE7D080D825B8839FF1766274EFF47', owner), - ('29CCA4544EA330D61591C784695C149C6B040022AC7B5B89CBD72800D10840EA', owner), - ('2B2298EAA26B9DC4A4558AE92E7BB0E4F85CF34BF848FDF636C0C11FBEC49897', owner), - ('2DCF8E8D817023D1E8E1451A3D68D6EC30D9BED94CBCB87F19DDC1CC0116AC1A', owner), - ('311A2AC55B50C09B30B3CC93B994A119153EEEAC54EF892FC447BBBD96101AA1', owner), - ('32AD3296829BC46DCFAC5EDDCB9DBF2C1EED5C11F83B2210CF9C6E60C798D4A7', owner), - ('340DA32B58331C8E2B561BAF300CA9DFD6B91CD2270EE0E2A34958B1C6259E85', owner), - ('362ED31D20B1E00392281231A96F0A0ACFDE02618953E695C9EF2EB0BAC37550', owner), - ('367A31E5838831AD2C074647886A6CDFF217E6B1BA910BFF85DC7A87AE9B5E98', owner), - ('3765D769C05BF98B427B3511903B2137E8A49B6F859D0AF159ED6A86786AA634', owner), - ('386D695CDF2D4576E01BCACCF5E49E78DA51AF9955C0B8FA7606373B007994B3', owner), - ('3A4F74BEAFAE2B9383AD8215D233A6CF3D057FB3C7E213E897BEEF4255FAEE9D', owner), - ('3AE76C45CA70E9180C1559981F42622DD251BCA1FBE6B901C52EC11673B03514', owner), - ('3BE8E7EB348D35C1928F19C769846788991641D1F6CF09514CA10269934F7359', owner), - ('3E3926F0B8A15AD5A14167BB647A843C3D4321E35DBC44DCE8C837417F2D28B0', owner), - ('400AC66D59B7B094A9E30B01A6BD013AFF1D30570F83E7592F421DBE5FF4BA8F', owner), - ('4185821F6DAB5BA8347B78A22B5F9A0A7570CA5C93A74D478A793D83BAC49805', owner), - ('41D1EEB177C0324E17DD6557F384E532DE0CF51A019A446B01EFB351BC259D77', owner), - ('45876B4DD861D45B3A94800774027A5DB45A48B2A729410908B6412F8A87E95D', owner), - ('4667BF250CD7C1A06B8474C613CDB1DF648A7F58736FBF57D05D6F755DAB67F4', owner), - ('47FF1B63B140B6FC04ED79131331E651DA5B2E2F170F5DAEF4153DC2FBC532B1', owner), - ('47FF1B63B140B6FC04ED79131331E651DA5B2E2F170F5DAEF4153DC2FBC532B1', owner), - ('57E6913AFACC5222BD76CDAF31F8ED88895464255374EF097A82D7F59AD39596', owner), - ('5890FA227121C76D90ED9E63C87E3A6533EEA0F6F0A1A23F1FC445139BC6BCDF', owner), - ('5D1E9ACBBB4A7D024B6852DF025970E2CED66FF622EE019CD0ED7FD841CCAD02', owner), - ('61341E07697978220EA61E85DCD2421343F2C1BF35CC5B8D0AD2F0226F391479', owner), - ('61CEC4A377BF5902C0FEAEE37034BF97D5BC6E0615E23A1CDFBAE6E3F5FB3CFD', owner), - ('631F0857B41845362C90C6980B4B10C4B628E23DBE24B6E96C128AE3DCB0D5AC', owner), - ('65B2E7CC18D903C331DF1152DF73CA0DC932D29F17997481C56F3087B2DD3147', owner), - ('66AA13A0EDC219384D9C425D3927E6ED4A5D1940C5E7CD4DAC88F5770103F2F1', owner), - ('6873D2F61C29BD52E954EEFF5977AA8367439997811A62FF212C948133C68D97', owner), - ('6DBBEAD23E8C860CF8B47F74FBFCA5204DE3E28B881313BB1D1ECCDC4747934E', owner), - ('6DEAD13257DFC3CCC6A4B37016BA91755FE9E0EC1F415030942E5ABC47F07C88', owner), - ('70A1450AF2AD395569AD0AFEB1D9C125324EE90AEC39C258880134D4892D51AB', owner), - ('72C26F827CEB92989798961BC6AE748D141E05D3EBCFB65D9041B266C920BE82', owner), - ('781764102188A8B4B173D4A8F5EC94D828647156097F99357A581E624B377509', owner), - ('788383A4C733BB87D2BF51673DC73E92DF15AB7D51DC715627AE77686D8D23BC', owner), - ('78B4EDCAABC8D9093E20E217802CAEB4F09E23A3394C4ACC6E87E8F35395310F', owner), - ('7F49CCB309323B1C7AB11C93C955B8C744F0A2B75C311F495E18906070500027', owner), - ('82ACBA48D5236CCFF7659AFC14594DEE902BD6082EF1A30A0B9B508628CF34F4', owner), - ('894D7839368F3298CC915AE8742EF330D7A26699F459478CF22C2B6BB2850166', owner), - ('8C0349D708571AE5AA21C11363482332073297D868F29058916529EFC520EF70', owner), - ('8D93D60C691959651476E5DC464BE12A85FA5280B6F524D4A1C3FCC9D048CFAD', owner), - ('9063F5FBC5E57AB6DE6C9488146020E172B176D5AB57D4C89F0F600E17FE2DE2', owner), - ('91656AA4EF493B3824A0B7263248E4E2D657A5C8488D880CB65B01730932FB53', owner), - ('91971C1497BF8E5BC68439ACC48D63EBB8FAABFD764DCBE82F3BA977CAC8CF6A', owner), - ('947078F97C6196968C3AE99C9A5D58667E86882CF6C8C9D58967A496BB7AF43C', owner), - ('96E4509450D380DAC362FF8E295589128A1F1CE55885D20D89C27BA2A9D00909', owner), - ('9783B5EE4492E9E891C655F1F48035959DAD453C0E623AF0FE7BF2C0A57885E3', owner), - ('97A51A094444620DF38CD8C6512CAC909A75FD437AE1E4D22929807661238127', owner), - ('97A8C5BA11D61FEFBB5D6A05DA4E15BA472DC4C6CD4972FC1A035DE321342FE4', owner), - ('992820E6EC8C41DAAE4BD8AB48F58268E943A670D35CA5E2BDCD3E7C4C94A072', owner), - ('992D359AA7A5F789D268B94C11B9485A6B1CE64362B0EDB4441CCC187C39647B', owner), - ('9954A1A99D55E8B189AB1BCA414B91F6A017191F6C40A86B6F3EF368DD860031', owner), - ('9BAF4F76D76BF5D6A897BFBD5F429BA14D04E08B48C3EE8D76930A828FFF3891', owner), - ('9C259FCB301D5FC7397ED5759963E0EF6B36E42057FD73046E6BD08B149F751C', owner), - ('9DD2DCB72F5E741627F2E9E03AB18503A3403CF6A904A479A4DB05D97E2250A9', owner), - ('9ED33F0FBC180BC032F8909CA2C4AB3418EDC33A45A50D2521A3B5876AA3EA2C', owner), - ('A4D978B7C4BDA15435D508F8B9592EC2A5ADFB12EA7BAD146A35ECB53094642F', owner), - ('A924D3CAD6DA42B7399B96A095A06F18F6B1ABA5B873B0D5F3A0EE2173B48B6C', owner), - ('AD3BE589C0474E97DE5BB2BF33534948B76BB80376DFDC58B1FED767B5A15BFC', owner), - ('B8D6B5E7857B45830E017C7BE3D856ADEB97C7290EB0665A3D473A4BEB51DCF3', owner), - ('B93F0699598F8B20FA0DACC12CFCFC1F2568793F6E779E04795E6D7C22530F75', owner), - ('BB01DA0333BB639C7E1C806DB0561DC98A5316F22FEF1090FB8D0BE46DAE499A', owner), - ('BC75F910FF320F5CB5999E66BBD4034F4AE537A42FDFEF35161C5348E366E216', owner), - ('BDD01126E9D85710D3FE75AF1CC1702A29F081B4F6FDF6A2B2135C0297A9CEC5', owner), - ('BE435DF7CD28AA2A7C8DB4FC8173475B77E5ABF392F76B7C76FA3F698CB71A9A', owner), - ('BEF7663BE5EA4DBFD8686E24701E036F4C03FB7FCD67A6C566ED94CE09C44470', owner), - ('C2469759C1947E14F4B65F72A9F5B3AF8B6F6E727B68BB0D91385CBF42176A8A', owner), - ('C3505BF3EC10A51DACE417C76B8BD10939A065D1F34E75B8A3065EE31CC69B96', owner), - ('C42D11C70CCF5E8CF3FB91FDF21D884021AD836CA68ADF2CBB7995C10BF588D4', owner), - ('C452AB846073DF5ACE25CCA64D6B7A09D906308A1A65EB5240E3C4EBCAA9CC0C', owner), - ('C69D64A5B839E41BA16742527E17056A18CE3C276FD26E34901A1BC7D0E32219', owner), - ('CB340011AFEB0D74C4A588B36EBAA441961608E8D2FA80DCA8C13872C850796B', owner), - ('CC8EEC6EB9212CBF897A5ACE7E8ABEECE1079F1A6DEF0A789591CB1547F1F084', owner), - ('CF13A243C1CD2E3C8CEB7E70100387CECBFB830525BBF9D0B70C79ADF3E84128', owner), - ('D89A11D16C488DD4FBBC541D4B07FAF8670D660994488FE54B1FBFF2704E4288', owner), - ('D9668AB52785086786C134B5E4BDDBF72452813B6973229AB92AA1A54D201BF5', owner), - ('DA3560FD0C32B54C83D4F2FF869003D2089369ACF2C89608F8AFA7436BFA4655', owner), - ('DF02AAB48387A9E1D4C65228089CB6ABE196C8F4B396C7E4BBC395DE136977F6', owner), - ('DF91AC85A94FCD0CFB8155BD7CBEFAAC14B8C5EE7397FE2CC85984459E2EA14E', owner), - ('E051B788ECBAEDA53046C70E6AF6058F95222C046157B8C4C1B9C2CFC65F46E5', owner), - ('E051B788ECBAEDA53046C70E6AF6058F95222C046157B8C4C1B9C2CFC65F46E5', owner), - ('E36DFC719D2114C2E39AEA88849E2845AB326F6F7FE74E0E539B7E54D81F3631', owner), - ('E39891F48BBCC593B8ED86CE82CE666FC1145B9FCBFD2B07BAD0A89BF4C7BFBF', owner), - ('E6856F137F79992DC94FA2F43297EC32D2D9A76F7BE66114C6A13EFC3BCDF5C8', owner), - ('EAFF8C85C208BA4D5B6B8046F5D6081747D779BADA7768E649D047FF9B1F660C', owner), - ('EE83A566496109A74F6AC6E410DF00BB29A290E0021516AE3B8A23288E7E2E72', owner), - ('EED7E0EFF2ED559E2A79EE361F9962AF3B1E999131E30BB7FD07546FAE0A7267', owner), - ('F1B4F6513B0D544A688D13ADC291EFA8C59F420CA5DCB23E0B5A06FA7E0D083D', owner), - ('F2A16D35B554694187A70D40CA682959F4F35C2CE0EAB8FD64F7AC2AB9F5C24A', owner), - ('F31FD461C5E99510403FC97C1DA2D8A9CBE270597D32BADF8FD66B77495F8D94', owner), - ('F48E6DD8718E953B60A24F2CBEA60A9521DEAE67DB25425B7D3ACE3C517DD9B7', owner), - ('C805603C4FA038776E42F263C604B49D96840322E1922D5606A9B0BBB5BFFE6F', owner), - ('1F16078CCE009DF62EDB9E7170E66CAAE670BCE71B8F92D38280C56AA372031D', owner), - ('37A480374DAF6202CE790C318A2BB8AA3797311261160A8E30558B7DEA78C7A6', owner), - ('408B8B3DF5ABB043521A493525023175AB1261B1DE21064D6BF247CE142153B9', owner), - ('540801DD345DC1C33EF431B35BF4C0E68BD319B577B9ABE1A9CFF1CBC39F548F', owner) + ("81D8FB4C9E2E7A8225656B4B8273B7CBA4B03EF2E9EB20E0A0291624ECA1BA86", owner), + ("B92AF298DC08049B78C77492D6551B710CD72AADA3D77BE54609E43278EF6E4D", owner), + ("E19DAE83C02E6F281358D4EBD11D7723B4F5EA0E357907D5443DECC5F93C1E9D", owner), + ("39DBC2288EF44B5F95332CB777E31103E840DBA680634AA806F5C9B100061802", owner), + ("32F5940CA29DD812A2C145E6FC89646628FFCC7C7A42CAE512337D8D29C40BBD", owner), + ("10D45FCBA396AEF3153EE8F6ECAE58AFE8476A280A2026FC71F6217DCF49BA2F", owner), + ("4B8668A5D465BCDD9000AA8DFCFF42044FCBD0AECE32FC7011A83E9160E89F09", owner), + ("89F3D1F6E485C334CD059D0995E3CDFDC00571B1849854847A44DC5548E2DCFB", owner), + ("C9EC350406F26E559AFFB4030DE2EBDE5435054C35A998605B8FCF04972D8D55", owner), + ("B3E506340FBF6B5786973393079F24B66BA46507E35E911DB0362A2ACDE97049", owner), + ("9F1863ED5717C394B42EF10A6607B144A65BA11FB6579DF94B8EB2F0C4CD60C1", owner), + ("DD59AF56084406E38C63FBE0850F30A0CD1277462A2192590FB05BC259E61273", owner), + ("DBAF9E056D3D5B38B68553304ABC88827EBC00F80CB9C7E197CDBC5822CD316C", owner), + ("65F3C0A01B8402D362B9722E98F75E5E991E6C186E934F7B2B2E6BE6DEC800EC", owner), + ("5B248E913D71853D3DA5AEDD8D9A4BC57A917126573817FB5FCB2D86A2F1C886", owner), + ("2679650FE341F2CF1EA883460B3556AAAF77A70D6B8DC484C9301D1B746CF7B5", owner), + ("BB1DD16D530008636F232303A7A86F3DFF969F848815C0574B12C2D787FEC93F", owner), + ("0CE02100F67C7EF85F4EED368F02BF7092380A3C23CA91FD7F19430D94B00C19", owner), + ("95049F0E4137C790B0D2767195E56F73807D123ADCF8F6E7BF2D4D991D305F89", owner), + ("02E6216ACAEF6401401FA555ECBED940B1A5F2569AED92956137AE58482EF1B7", owner), + ("6EFEFE0B5B01478B7B944C10D3A8ACA2CCA4208888E2059F8A06CB5824D7BAB0", owner), + ("9D00AE4CD47A41C783DC48F342C076C2C16F3413F4D2DF50D181CA3BB5AD859D", owner), + ("D8D4E6DDF6E42D74A6A536EA62FD1217E4290B145C9E5C3695A31B42EFB5F5A4", owner), + ("F277AF4F9BDC918AE89FA35CC1B34E34984C04AE9765322C3CB049574D36509C", owner), + ("0DC24C75EB1AEF56B9F13AB9DE60E2ECA1C4510034E290BBB36CF60A549B234C", owner), + ("835881F2A5572D7059B5C8635018552892E945626F115FC9CA07ACF7BDE857A4", owner), + ("BADFF5E4F0FEA711701CA8FB22E4C43821E31E210CF52D1D4F74DD50F1D039BC", owner), + ("C452AB846073DF5ACE25CCA64D6B7A09D906308A1A65EB5240E3C4EBCAA9CC0C", owner), + ("F1863EC8B7F43F94AD14FB0B8B4A69497A8C65ECBC2A55E0BB420E772B8CDC91", owner), + ("7BC9CB5463CE0F011FB5085EB8BA77D1ACD283C43F4A57603CC113F22CEBC579", owner), + ("E800395DBE0E045781E8005178B4BAF5A257F06E159121A67C595F6AE22506FD", owner), + ("1CB4DCCAF2C812CFA7B4938E1371FE2B96910FE407216FD95428672D6C7E7316", owner), + ("3ECE27CBB3EC4438CCE523B927C4F05FDC5C593A3766DB984C5E437A3FF6A16B", owner), + ("68EE4632C7BE1C66C83E89DD93EAEE1294159ABF45B4C2C72D7DC7499AA2A043", owner), + ("E24B315A551671483D8B9073B32DE11B4DE1EB2EAB211AFD2D9C319FF55E08D0", owner), + ("E7C20B3AB481EC885501ECA5293781D84B5A1AC24F88266B5270E7ECB4AA2538", owner), + ("7EAC80A915C84CD4AFEC638904D94EB168A8557951A4D539B0713028552B6B8C", owner), + ("E7681F153121EA1E67F74BBCB0CDC5E502702C1B8CC55FB65D702DFBA948B5F4", owner), + ("DCCC3CE1C00EE4B0B10487D372A0FA47F5C26F57A359BE7B27801E144EACBAC4", owner), + ("0257FF710F2A16E489B37493C07604A7CDA96129D8A8FD68D2B6AF633904315D", owner), + ("3A91F0F9E5287FA2994C7D930B2C1A5EE14CE8E1C8304AE495ADC58CC4453C0C", owner), + ("495300790E6C9BF2510DABA59DB3D57E9D2B85D7D7640434EC75BAA3851C74E5", owner), + ("81A8B2C9751AEB1FABA7DBDE5EE9691DC0EAEE2A31C38B1491A8146756A6B770", owner), + ("8E53EFDC15F852CEE5A6E92931BC42E6163CD30FF649CCA7E87252C3A459960B", owner), + ("992D359AA7A5F789D268B94C11B9485A6B1CE64362B0EDB4441CCC187C39647B", owner), + ("9FA4D5023FD43ECAFF4200BA7E8D4353259D2B7E5E72B5096EFF8027D66D1043", owner), + ("D372C0D0F4FDC9F52E9E1F23FC56EE72414A17F350D0CEA6C26A35A6C3217A13", owner), + ("5C5805196A85E93789457017D4F9EB6828B97C41CB9BA6D3DC1FCC115F527A55", owner), + ("804E354C6368BB27A90FAE8E498A57052B293418259A019C4F53A2007254490F", owner), + ("03F64A29948A88BEFFDB035E0B09A7370CCF0CD9CE6BCF8E640C2107318FAB87", owner), + ("05D87E15713454616F5B0ED7849AB5C1712AB84F02349478EC2A38F970C01489", owner), + ("06EB5BADD26E4FAE65F9A42358DEEF7C18E52CC05FBB7FC76776E69D1B982A14", owner), + ("08BB2289E9E91B4D20FF3F1562516AB07E979B2C6CEFE2AB70C6DFC1199F8DA5", owner), + ("0928F0408BF725E61D67D87138A8EEBC52962D2847F16E3587163B160E41B6AD", owner), + ("09F98AA90F85198C0D73F89BA77E87EC6F596C491350FB8F8BBA80A62FBB914B", owner), + ("0A75EA0B1D70EAA4D3F374246DB54FC7B43E7F596A353309B9C36B4FD975725E", owner), + ("0C51D7906FC4931149765DA88682426B2CFE9E6AA4F27253EAB400111432E3A7", owner), + ("0FA3A29AD05130D7FE5BF4D2596563CDED1D874096AACC181069932A2E49519A", owner), + ("147730B42F11FE493FE902B6251E97CD2B6F34D36AF59330F11D02A42F940D07", owner), + ("148FE18F715A9FCFE1A444CE0FFF7F85869EB422330DC04B314C0F295D6DA79E", owner), + ("1B909115A8D473E51328A87823BD621CE655DFAE54FA2BFA72FDC0298611D6B8", owner), + ("1D8B58C1FDB8DA8B33CCEE1E5F973AF734D90EF317E33F5DB1573C2BA088A80C", owner), + ("1F179186EFDF5EF2DE018245BA0EAE8134868601BA0D35FF3D9865C1537CED93", owner), + ("270C84B29D86F16312B06AAAE4EBB8DFF8DE7D080D825B8839FF1766274EFF47", owner), + ("29CCA4544EA330D61591C784695C149C6B040022AC7B5B89CBD72800D10840EA", owner), + ("2B2298EAA26B9DC4A4558AE92E7BB0E4F85CF34BF848FDF636C0C11FBEC49897", owner), + ("2DCF8E8D817023D1E8E1451A3D68D6EC30D9BED94CBCB87F19DDC1CC0116AC1A", owner), + ("311A2AC55B50C09B30B3CC93B994A119153EEEAC54EF892FC447BBBD96101AA1", owner), + ("32AD3296829BC46DCFAC5EDDCB9DBF2C1EED5C11F83B2210CF9C6E60C798D4A7", owner), + ("340DA32B58331C8E2B561BAF300CA9DFD6B91CD2270EE0E2A34958B1C6259E85", owner), + ("362ED31D20B1E00392281231A96F0A0ACFDE02618953E695C9EF2EB0BAC37550", owner), + ("367A31E5838831AD2C074647886A6CDFF217E6B1BA910BFF85DC7A87AE9B5E98", owner), + ("3765D769C05BF98B427B3511903B2137E8A49B6F859D0AF159ED6A86786AA634", owner), + ("386D695CDF2D4576E01BCACCF5E49E78DA51AF9955C0B8FA7606373B007994B3", owner), + ("3A4F74BEAFAE2B9383AD8215D233A6CF3D057FB3C7E213E897BEEF4255FAEE9D", owner), + ("3AE76C45CA70E9180C1559981F42622DD251BCA1FBE6B901C52EC11673B03514", owner), + ("3BE8E7EB348D35C1928F19C769846788991641D1F6CF09514CA10269934F7359", owner), + ("3E3926F0B8A15AD5A14167BB647A843C3D4321E35DBC44DCE8C837417F2D28B0", owner), + ("400AC66D59B7B094A9E30B01A6BD013AFF1D30570F83E7592F421DBE5FF4BA8F", owner), + ("4185821F6DAB5BA8347B78A22B5F9A0A7570CA5C93A74D478A793D83BAC49805", owner), + ("41D1EEB177C0324E17DD6557F384E532DE0CF51A019A446B01EFB351BC259D77", owner), + ("45876B4DD861D45B3A94800774027A5DB45A48B2A729410908B6412F8A87E95D", owner), + ("4667BF250CD7C1A06B8474C613CDB1DF648A7F58736FBF57D05D6F755DAB67F4", owner), + ("47FF1B63B140B6FC04ED79131331E651DA5B2E2F170F5DAEF4153DC2FBC532B1", owner), + ("47FF1B63B140B6FC04ED79131331E651DA5B2E2F170F5DAEF4153DC2FBC532B1", owner), + ("57E6913AFACC5222BD76CDAF31F8ED88895464255374EF097A82D7F59AD39596", owner), + ("5890FA227121C76D90ED9E63C87E3A6533EEA0F6F0A1A23F1FC445139BC6BCDF", owner), + ("5D1E9ACBBB4A7D024B6852DF025970E2CED66FF622EE019CD0ED7FD841CCAD02", owner), + ("61341E07697978220EA61E85DCD2421343F2C1BF35CC5B8D0AD2F0226F391479", owner), + ("61CEC4A377BF5902C0FEAEE37034BF97D5BC6E0615E23A1CDFBAE6E3F5FB3CFD", owner), + ("631F0857B41845362C90C6980B4B10C4B628E23DBE24B6E96C128AE3DCB0D5AC", owner), + ("65B2E7CC18D903C331DF1152DF73CA0DC932D29F17997481C56F3087B2DD3147", owner), + ("66AA13A0EDC219384D9C425D3927E6ED4A5D1940C5E7CD4DAC88F5770103F2F1", owner), + ("6873D2F61C29BD52E954EEFF5977AA8367439997811A62FF212C948133C68D97", owner), + ("6DBBEAD23E8C860CF8B47F74FBFCA5204DE3E28B881313BB1D1ECCDC4747934E", owner), + ("6DEAD13257DFC3CCC6A4B37016BA91755FE9E0EC1F415030942E5ABC47F07C88", owner), + ("70A1450AF2AD395569AD0AFEB1D9C125324EE90AEC39C258880134D4892D51AB", owner), + ("72C26F827CEB92989798961BC6AE748D141E05D3EBCFB65D9041B266C920BE82", owner), + ("781764102188A8B4B173D4A8F5EC94D828647156097F99357A581E624B377509", owner), + ("788383A4C733BB87D2BF51673DC73E92DF15AB7D51DC715627AE77686D8D23BC", owner), + ("78B4EDCAABC8D9093E20E217802CAEB4F09E23A3394C4ACC6E87E8F35395310F", owner), + ("7F49CCB309323B1C7AB11C93C955B8C744F0A2B75C311F495E18906070500027", owner), + ("82ACBA48D5236CCFF7659AFC14594DEE902BD6082EF1A30A0B9B508628CF34F4", owner), + ("894D7839368F3298CC915AE8742EF330D7A26699F459478CF22C2B6BB2850166", owner), + ("8C0349D708571AE5AA21C11363482332073297D868F29058916529EFC520EF70", owner), + ("8D93D60C691959651476E5DC464BE12A85FA5280B6F524D4A1C3FCC9D048CFAD", owner), + ("9063F5FBC5E57AB6DE6C9488146020E172B176D5AB57D4C89F0F600E17FE2DE2", owner), + ("91656AA4EF493B3824A0B7263248E4E2D657A5C8488D880CB65B01730932FB53", owner), + ("91971C1497BF8E5BC68439ACC48D63EBB8FAABFD764DCBE82F3BA977CAC8CF6A", owner), + ("947078F97C6196968C3AE99C9A5D58667E86882CF6C8C9D58967A496BB7AF43C", owner), + ("96E4509450D380DAC362FF8E295589128A1F1CE55885D20D89C27BA2A9D00909", owner), + ("9783B5EE4492E9E891C655F1F48035959DAD453C0E623AF0FE7BF2C0A57885E3", owner), + ("97A51A094444620DF38CD8C6512CAC909A75FD437AE1E4D22929807661238127", owner), + ("97A8C5BA11D61FEFBB5D6A05DA4E15BA472DC4C6CD4972FC1A035DE321342FE4", owner), + ("992820E6EC8C41DAAE4BD8AB48F58268E943A670D35CA5E2BDCD3E7C4C94A072", owner), + ("992D359AA7A5F789D268B94C11B9485A6B1CE64362B0EDB4441CCC187C39647B", owner), + ("9954A1A99D55E8B189AB1BCA414B91F6A017191F6C40A86B6F3EF368DD860031", owner), + ("9BAF4F76D76BF5D6A897BFBD5F429BA14D04E08B48C3EE8D76930A828FFF3891", owner), + ("9C259FCB301D5FC7397ED5759963E0EF6B36E42057FD73046E6BD08B149F751C", owner), + ("9DD2DCB72F5E741627F2E9E03AB18503A3403CF6A904A479A4DB05D97E2250A9", owner), + ("9ED33F0FBC180BC032F8909CA2C4AB3418EDC33A45A50D2521A3B5876AA3EA2C", owner), + ("A4D978B7C4BDA15435D508F8B9592EC2A5ADFB12EA7BAD146A35ECB53094642F", owner), + ("A924D3CAD6DA42B7399B96A095A06F18F6B1ABA5B873B0D5F3A0EE2173B48B6C", owner), + ("AD3BE589C0474E97DE5BB2BF33534948B76BB80376DFDC58B1FED767B5A15BFC", owner), + ("B8D6B5E7857B45830E017C7BE3D856ADEB97C7290EB0665A3D473A4BEB51DCF3", owner), + ("B93F0699598F8B20FA0DACC12CFCFC1F2568793F6E779E04795E6D7C22530F75", owner), + ("BB01DA0333BB639C7E1C806DB0561DC98A5316F22FEF1090FB8D0BE46DAE499A", owner), + ("BC75F910FF320F5CB5999E66BBD4034F4AE537A42FDFEF35161C5348E366E216", owner), + ("BDD01126E9D85710D3FE75AF1CC1702A29F081B4F6FDF6A2B2135C0297A9CEC5", owner), + ("BE435DF7CD28AA2A7C8DB4FC8173475B77E5ABF392F76B7C76FA3F698CB71A9A", owner), + ("BEF7663BE5EA4DBFD8686E24701E036F4C03FB7FCD67A6C566ED94CE09C44470", owner), + ("C2469759C1947E14F4B65F72A9F5B3AF8B6F6E727B68BB0D91385CBF42176A8A", owner), + ("C3505BF3EC10A51DACE417C76B8BD10939A065D1F34E75B8A3065EE31CC69B96", owner), + ("C42D11C70CCF5E8CF3FB91FDF21D884021AD836CA68ADF2CBB7995C10BF588D4", owner), + ("C452AB846073DF5ACE25CCA64D6B7A09D906308A1A65EB5240E3C4EBCAA9CC0C", owner), + ("C69D64A5B839E41BA16742527E17056A18CE3C276FD26E34901A1BC7D0E32219", owner), + ("CB340011AFEB0D74C4A588B36EBAA441961608E8D2FA80DCA8C13872C850796B", owner), + ("CC8EEC6EB9212CBF897A5ACE7E8ABEECE1079F1A6DEF0A789591CB1547F1F084", owner), + ("CF13A243C1CD2E3C8CEB7E70100387CECBFB830525BBF9D0B70C79ADF3E84128", owner), + ("D89A11D16C488DD4FBBC541D4B07FAF8670D660994488FE54B1FBFF2704E4288", owner), + ("D9668AB52785086786C134B5E4BDDBF72452813B6973229AB92AA1A54D201BF5", owner), + ("DA3560FD0C32B54C83D4F2FF869003D2089369ACF2C89608F8AFA7436BFA4655", owner), + ("DF02AAB48387A9E1D4C65228089CB6ABE196C8F4B396C7E4BBC395DE136977F6", owner), + ("DF91AC85A94FCD0CFB8155BD7CBEFAAC14B8C5EE7397FE2CC85984459E2EA14E", owner), + ("E051B788ECBAEDA53046C70E6AF6058F95222C046157B8C4C1B9C2CFC65F46E5", owner), + ("E051B788ECBAEDA53046C70E6AF6058F95222C046157B8C4C1B9C2CFC65F46E5", owner), + ("E36DFC719D2114C2E39AEA88849E2845AB326F6F7FE74E0E539B7E54D81F3631", owner), + ("E39891F48BBCC593B8ED86CE82CE666FC1145B9FCBFD2B07BAD0A89BF4C7BFBF", owner), + ("E6856F137F79992DC94FA2F43297EC32D2D9A76F7BE66114C6A13EFC3BCDF5C8", owner), + ("EAFF8C85C208BA4D5B6B8046F5D6081747D779BADA7768E649D047FF9B1F660C", owner), + ("EE83A566496109A74F6AC6E410DF00BB29A290E0021516AE3B8A23288E7E2E72", owner), + ("EED7E0EFF2ED559E2A79EE361F9962AF3B1E999131E30BB7FD07546FAE0A7267", owner), + ("F1B4F6513B0D544A688D13ADC291EFA8C59F420CA5DCB23E0B5A06FA7E0D083D", owner), + ("F2A16D35B554694187A70D40CA682959F4F35C2CE0EAB8FD64F7AC2AB9F5C24A", owner), + ("F31FD461C5E99510403FC97C1DA2D8A9CBE270597D32BADF8FD66B77495F8D94", owner), + ("F48E6DD8718E953B60A24F2CBEA60A9521DEAE67DB25425B7D3ACE3C517DD9B7", owner), + ("C805603C4FA038776E42F263C604B49D96840322E1922D5606A9B0BBB5BFFE6F", owner), + ("1F16078CCE009DF62EDB9E7170E66CAAE670BCE71B8F92D38280C56AA372031D", owner), + ("37A480374DAF6202CE790C318A2BB8AA3797311261160A8E30558B7DEA78C7A6", owner), + ("408B8B3DF5ABB043521A493525023175AB1261B1DE21064D6BF247CE142153B9", owner), + ("540801DD345DC1C33EF431B35BF4C0E68BD319B577B9ABE1A9CFF1CBC39F548F", owner), ] newHash_esl = sha256_esl_builder(new_hashes) @@ -369,250 +365,250 @@ def BootHoleData(): # Now prepare the duplicate data, these were the 4 dupes in the new list that were not de-duped by EDK2 expected_dupes = [ - ('47FF1B63B140B6FC04ED79131331E651DA5B2E2F170F5DAEF4153DC2FBC532B1', owner), - ('992D359AA7A5F789D268B94C11B9485A6B1CE64362B0EDB4441CCC187C39647B', owner), - ('C452AB846073DF5ACE25CCA64D6B7A09D906308A1A65EB5240E3C4EBCAA9CC0C', owner), - ('E051B788ECBAEDA53046C70E6AF6058F95222C046157B8C4C1B9C2CFC65F46E5', owner) + ("47FF1B63B140B6FC04ED79131331E651DA5B2E2F170F5DAEF4153DC2FBC532B1", owner), + ("992D359AA7A5F789D268B94C11B9485A6B1CE64362B0EDB4441CCC187C39647B", owner), + ("C452AB846073DF5ACE25CCA64D6B7A09D906308A1A65EB5240E3C4EBCAA9CC0C", owner), + ("E051B788ECBAEDA53046C70E6AF6058F95222C046157B8C4C1B9C2CFC65F46E5", owner), ] expected_dupes_esl = sha256_esl_builder(expected_dupes) expected_dupes_esd = EfiSignatureDatabase(esl_list=[expected_dupes_esl]) # Now prepare the canonicalized data canonical_hashes = [ - ('0257FF710F2A16E489B37493C07604A7CDA96129D8A8FD68D2B6AF633904315D', owner), - ('02E6216ACAEF6401401FA555ECBED940B1A5F2569AED92956137AE58482EF1B7', owner), - ('03F64A29948A88BEFFDB035E0B09A7370CCF0CD9CE6BCF8E640C2107318FAB87', owner), - ('05D87E15713454616F5B0ED7849AB5C1712AB84F02349478EC2A38F970C01489', owner), - ('06EB5BADD26E4FAE65F9A42358DEEF7C18E52CC05FBB7FC76776E69D1B982A14', owner), - ('075EEA060589548BA060B2FEED10DA3C20C7FE9B17CD026B94E8A683B8115238', owner), - ('07E6C6A858646FB1EFC67903FE28B116011F2367FE92E6BE2B36999EFF39D09E', owner), - ('08BB2289E9E91B4D20FF3F1562516AB07E979B2C6CEFE2AB70C6DFC1199F8DA5', owner), - ('0928F0408BF725E61D67D87138A8EEBC52962D2847F16E3587163B160E41B6AD', owner), - ('09DF5F4E511208EC78B96D12D08125FDB603868DE39F6F72927852599B659C26', owner), - ('09F98AA90F85198C0D73F89BA77E87EC6F596C491350FB8F8BBA80A62FBB914B', owner), - ('0A75EA0B1D70EAA4D3F374246DB54FC7B43E7F596A353309B9C36B4FD975725E', owner), - ('0BBB4392DAAC7AB89B30A4AC657531B97BFAAB04F90B0DAFE5F9B6EB90A06374', owner), - ('0C189339762DF336AB3DD006A463DF715A39CFB0F492465C600E6C6BD7BD898C', owner), - ('0C51D7906FC4931149765DA88682426B2CFE9E6AA4F27253EAB400111432E3A7', owner), - ('0CE02100F67C7EF85F4EED368F02BF7092380A3C23CA91FD7F19430D94B00C19', owner), - ('0D0DBECA6F29ECA06F331A7D72E4884B12097FB348983A2A14A0D73F4F10140F', owner), - ('0DC24C75EB1AEF56B9F13AB9DE60E2ECA1C4510034E290BBB36CF60A549B234C', owner), - ('0DC9F3FB99962148C3CA833632758D3ED4FC8D0B0007B95B31E6528F2ACD5BFC', owner), - ('0FA3A29AD05130D7FE5BF4D2596563CDED1D874096AACC181069932A2E49519A', owner), - ('106FACEACFECFD4E303B74F480A08098E2D0802B936F8EC774CE21F31686689C', owner), - ('10D45FCBA396AEF3153EE8F6ECAE58AFE8476A280A2026FC71F6217DCF49BA2F', owner), - ('147730B42F11FE493FE902B6251E97CD2B6F34D36AF59330F11D02A42F940D07', owner), - ('148FE18F715A9FCFE1A444CE0FFF7F85869EB422330DC04B314C0F295D6DA79E', owner), - ('174E3A0B5B43C6A607BBD3404F05341E3DCF396267CE94F8B50E2E23A9DA920C', owner), - ('18333429FF0562ED9F97033E1148DCEEE52DBE2E496D5410B5CFD6C864D2D10F', owner), - ('1AEC84B84B6C65A51220A9BE7181965230210D62D6D33C48999C6B295A2B0A06', owner), - ('1B909115A8D473E51328A87823BD621CE655DFAE54FA2BFA72FDC0298611D6B8', owner), - ('1CB4DCCAF2C812CFA7B4938E1371FE2B96910FE407216FD95428672D6C7E7316', owner), - ('1D8B58C1FDB8DA8B33CCEE1E5F973AF734D90EF317E33F5DB1573C2BA088A80C', owner), - ('1F16078CCE009DF62EDB9E7170E66CAAE670BCE71B8F92D38280C56AA372031D', owner), - ('1F179186EFDF5EF2DE018245BA0EAE8134868601BA0D35FF3D9865C1537CED93', owner), - ('2679650FE341F2CF1EA883460B3556AAAF77A70D6B8DC484C9301D1B746CF7B5', owner), - ('270C84B29D86F16312B06AAAE4EBB8DFF8DE7D080D825B8839FF1766274EFF47', owner), - ('29C6EB52B43C3AA18B2CD8ED6EA8607CEF3CFAE1BAFE1165755CF2E614844A44', owner), - ('29CCA4544EA330D61591C784695C149C6B040022AC7B5B89CBD72800D10840EA', owner), - ('2B2298EAA26B9DC4A4558AE92E7BB0E4F85CF34BF848FDF636C0C11FBEC49897', owner), - ('2B99CF26422E92FE365FBF4BC30D27086C9EE14B7A6FFF44FB2F6B9001699939', owner), - ('2BBF2CA7B8F1D91F27EE52B6FB2A5DD049B85A2B9B529C5D6662068104B055F8', owner), - ('2C73D93325BA6DCBE589D4A4C63C5B935559EF92FBF050ED50C4E2085206F17D', owner), - ('2DCF8E8D817023D1E8E1451A3D68D6EC30D9BED94CBCB87F19DDC1CC0116AC1A', owner), - ('2E70916786A6F773511FA7181FAB0F1D70B557C6322EA923B2A8D3B92B51AF7D', owner), - ('306628FA5477305728BA4A467DE7D0387A54F569D3769FCE5E75EC89D28D1593', owner), - ('311A2AC55B50C09B30B3CC93B994A119153EEEAC54EF892FC447BBBD96101AA1', owner), - ('32AD3296829BC46DCFAC5EDDCB9DBF2C1EED5C11F83B2210CF9C6E60C798D4A7', owner), - ('32F5940CA29DD812A2C145E6FC89646628FFCC7C7A42CAE512337D8D29C40BBD', owner), - ('340DA32B58331C8E2B561BAF300CA9DFD6B91CD2270EE0E2A34958B1C6259E85', owner), - ('3608EDBAF5AD0F41A414A1777ABF2FAF5E670334675EC3995E6935829E0CAAD2', owner), - ('362ED31D20B1E00392281231A96F0A0ACFDE02618953E695C9EF2EB0BAC37550', owner), - ('363384D14D1F2E0B7815626484C459AD57A318EF4396266048D058C5A19BBF76', owner), - ('367A31E5838831AD2C074647886A6CDFF217E6B1BA910BFF85DC7A87AE9B5E98', owner), - ('3765D769C05BF98B427B3511903B2137E8A49B6F859D0AF159ED6A86786AA634', owner), - ('37A480374DAF6202CE790C318A2BB8AA3797311261160A8E30558B7DEA78C7A6', owner), - ('3841D221368D1583D75C0A02E62160394D6C4E0A6760B6F607B90362BC855B02', owner), - ('386D695CDF2D4576E01BCACCF5E49E78DA51AF9955C0B8FA7606373B007994B3', owner), - ('39DBC2288EF44B5F95332CB777E31103E840DBA680634AA806F5C9B100061802', owner), - ('3A4F74BEAFAE2B9383AD8215D233A6CF3D057FB3C7E213E897BEEF4255FAEE9D', owner), - ('3A91F0F9E5287FA2994C7D930B2C1A5EE14CE8E1C8304AE495ADC58CC4453C0C', owner), - ('3AE76C45CA70E9180C1559981F42622DD251BCA1FBE6B901C52EC11673B03514', owner), - ('3B0287533E0CC3D0EC1AA823CBF0A941AAD8721579D1C499802DD1C3A636B8A9', owner), - ('3BE8E7EB348D35C1928F19C769846788991641D1F6CF09514CA10269934F7359', owner), - ('3E3926F0B8A15AD5A14167BB647A843C3D4321E35DBC44DCE8C837417F2D28B0', owner), - ('3ECE27CBB3EC4438CCE523B927C4F05FDC5C593A3766DB984C5E437A3FF6A16B', owner), - ('3FCE9B9FDF3EF09D5452B0F95EE481C2B7F06D743A737971558E70136ACE3E73', owner), - ('400AC66D59B7B094A9E30B01A6BD013AFF1D30570F83E7592F421DBE5FF4BA8F', owner), - ('408B8B3DF5ABB043521A493525023175AB1261B1DE21064D6BF247CE142153B9', owner), - ('4185821F6DAB5BA8347B78A22B5F9A0A7570CA5C93A74D478A793D83BAC49805', owner), - ('41D1EEB177C0324E17DD6557F384E532DE0CF51A019A446B01EFB351BC259D77', owner), - ('4397DACA839E7F63077CB50C92DF43BC2D2FB2A8F59F26FC7A0E4BD4D9751692', owner), - ('45876B4DD861D45B3A94800774027A5DB45A48B2A729410908B6412F8A87E95D', owner), - ('45C7C8AE750ACFBB48FC37527D6412DD644DAED8913CCD8A24C94D856967DF8E', owner), - ('4667BF250CD7C1A06B8474C613CDB1DF648A7F58736FBF57D05D6F755DAB67F4', owner), - ('47CC086127E2069A86E03A6BEF2CD410F8C55A6D6BDB362168C31B2CE32A5ADF', owner), - ('47FF1B63B140B6FC04ED79131331E651DA5B2E2F170F5DAEF4153DC2FBC532B1', owner), - ('495300790E6C9BF2510DABA59DB3D57E9D2B85D7D7640434EC75BAA3851C74E5', owner), - ('4B8668A5D465BCDD9000AA8DFCFF42044FCBD0AECE32FC7011A83E9160E89F09', owner), - ('518831FE7382B514D03E15C621228B8AB65479BD0CBFA3C5C1D0F48D9C306135', owner), - ('5391C3A2FB112102A6AA1EDC25AE77E19F5D6F09CD09EEB2509922BFCD5992EA', owner), - ('540801DD345DC1C33EF431B35BF4C0E68BD319B577B9ABE1A9CFF1CBC39F548F', owner), - ('55B99B0DE53DBCFE485AA9C737CF3FB616EF3D91FAB599AA7CAB19EDA763B5BA', owner), - ('57E6913AFACC5222BD76CDAF31F8ED88895464255374EF097A82D7F59AD39596', owner), - ('5890FA227121C76D90ED9E63C87E3A6533EEA0F6F0A1A23F1FC445139BC6BCDF', owner), - ('58FB941AEF95A25943B3FB5F2510A0DF3FE44C58C95E0AB80487297568AB9771', owner), - ('5AE949EA8855EB93E439DBC65BDA2E42852C2FDF6789FA146736E3C3410F2B5C', owner), - ('5B248E913D71853D3DA5AEDD8D9A4BC57A917126573817FB5FCB2D86A2F1C886', owner), - ('5C5805196A85E93789457017D4F9EB6828B97C41CB9BA6D3DC1FCC115F527A55', owner), - ('5D1E9ACBBB4A7D024B6852DF025970E2CED66FF622EE019CD0ED7FD841CCAD02', owner), - ('61341E07697978220EA61E85DCD2421343F2C1BF35CC5B8D0AD2F0226F391479', owner), - ('61CEC4A377BF5902C0FEAEE37034BF97D5BC6E0615E23A1CDFBAE6E3F5FB3CFD', owner), - ('631F0857B41845362C90C6980B4B10C4B628E23DBE24B6E96C128AE3DCB0D5AC', owner), - ('64575BD912789A2E14AD56F6341F52AF6BF80CF94400785975E9F04E2D64D745', owner), - ('65B2E7CC18D903C331DF1152DF73CA0DC932D29F17997481C56F3087B2DD3147', owner), - ('65F3C0A01B8402D362B9722E98F75E5E991E6C186E934F7B2B2E6BE6DEC800EC', owner), - ('66AA13A0EDC219384D9C425D3927E6ED4A5D1940C5E7CD4DAC88F5770103F2F1', owner), - ('6873D2F61C29BD52E954EEFF5977AA8367439997811A62FF212C948133C68D97', owner), - ('68EE4632C7BE1C66C83E89DD93EAEE1294159ABF45B4C2C72D7DC7499AA2A043', owner), - ('6B1D138078E4418AA68DEB7BB35E066092CF479EEB8CE4CD12E7D072CCB42F66', owner), - ('6C8854478DD559E29351B826C06CB8BFEF2B94AD3538358772D193F82ED1CA11', owner), - ('6DBBEAD23E8C860CF8B47F74FBFCA5204DE3E28B881313BB1D1ECCDC4747934E', owner), - ('6DEAD13257DFC3CCC6A4B37016BA91755FE9E0EC1F415030942E5ABC47F07C88', owner), - ('6EFEFE0B5B01478B7B944C10D3A8ACA2CCA4208888E2059F8A06CB5824D7BAB0', owner), - ('6F1428FF71C9DB0ED5AF1F2E7BBFCBAB647CC265DDF5B293CDB626F50A3A785E', owner), - ('70A1450AF2AD395569AD0AFEB1D9C125324EE90AEC39C258880134D4892D51AB', owner), - ('71F2906FD222497E54A34662AB2497FCC81020770FF51368E9E3D9BFCBFD6375', owner), - ('726B3EB654046A30F3F83D9B96CE03F670E9A806D1708A0371E62DC49D2C23C1', owner), - ('72C26F827CEB92989798961BC6AE748D141E05D3EBCFB65D9041B266C920BE82', owner), - ('72E0BD1867CF5D9D56AB158ADF3BDDBC82BF32A8D8AA1D8C5E2F6DF29428D6D8', owner), - ('77DD190FA30D88FF5E3B011A0AE61E6209780C130B535ECB87E6F0888A0B6B2F', owner), - ('781764102188A8B4B173D4A8F5EC94D828647156097F99357A581E624B377509', owner), - ('7827AF99362CFAF0717DADE4B1BFE0438AD171C15ADDC248B75BF8CAA44BB2C5', owner), - ('788383A4C733BB87D2BF51673DC73E92DF15AB7D51DC715627AE77686D8D23BC', owner), - ('78B4EDCAABC8D9093E20E217802CAEB4F09E23A3394C4ACC6E87E8F35395310F', owner), - ('7BC9CB5463CE0F011FB5085EB8BA77D1ACD283C43F4A57603CC113F22CEBC579', owner), - ('7EAC80A915C84CD4AFEC638904D94EB168A8557951A4D539B0713028552B6B8C', owner), - ('7F49CCB309323B1C7AB11C93C955B8C744F0A2B75C311F495E18906070500027', owner), - ('804E354C6368BB27A90FAE8E498A57052B293418259A019C4F53A2007254490F', owner), - ('80B4D96931BF0D02FD91A61E19D14F1DA452E66DB2408CA8604D411F92659F0A', owner), - ('81A8B2C9751AEB1FABA7DBDE5EE9691DC0EAEE2A31C38B1491A8146756A6B770', owner), - ('81A8B965BB84D3876B9429A95481CC955318CFAA1412D808C8A33BFD33FFF0E4', owner), - ('81D8FB4C9E2E7A8225656B4B8273B7CBA4B03EF2E9EB20E0A0291624ECA1BA86', owner), - ('82ACBA48D5236CCFF7659AFC14594DEE902BD6082EF1A30A0B9B508628CF34F4', owner), - ('82DB3BCEB4F60843CE9D97C3D187CD9B5941CD3DE8100E586F2BDA5637575F67', owner), - ('835881F2A5572D7059B5C8635018552892E945626F115FC9CA07ACF7BDE857A4', owner), - ('894D7839368F3298CC915AE8742EF330D7A26699F459478CF22C2B6BB2850166', owner), - ('895A9785F617CA1D7ED44FC1A1470B71F3F1223862D9FF9DCC3AE2DF92163DAF', owner), - ('89F3D1F6E485C334CD059D0995E3CDFDC00571B1849854847A44DC5548E2DCFB', owner), - ('8AD64859F195B5F58DAFAA940B6A6167ACD67A886E8F469364177221C55945B9', owner), - ('8BF434B49E00CCF71502A2CD900865CB01EC3B3DA03C35BE505FDF7BD563F521', owner), - ('8C0349D708571AE5AA21C11363482332073297D868F29058916529EFC520EF70', owner), - ('8D8EA289CFE70A1C07AB7365CB28EE51EDD33CF2506DE888FBADD60EBF80481C', owner), - ('8D93D60C691959651476E5DC464BE12A85FA5280B6F524D4A1C3FCC9D048CFAD', owner), - ('8E53EFDC15F852CEE5A6E92931BC42E6163CD30FF649CCA7E87252C3A459960B', owner), - ('9063F5FBC5E57AB6DE6C9488146020E172B176D5AB57D4C89F0F600E17FE2DE2', owner), - ('90FBE70E69D633408D3E170C6832DBB2D209E0272527DFB63D49D29572A6F44C', owner), - ('91656AA4EF493B3824A0B7263248E4E2D657A5C8488D880CB65B01730932FB53', owner), - ('91971C1497BF8E5BC68439ACC48D63EBB8FAABFD764DCBE82F3BA977CAC8CF6A', owner), - ('939AEEF4F5FA51E23340C3F2E49048CE8872526AFDF752C3A7F3A3F2BC9F6049', owner), - ('947078F97C6196968C3AE99C9A5D58667E86882CF6C8C9D58967A496BB7AF43C', owner), - ('95049F0E4137C790B0D2767195E56F73807D123ADCF8F6E7BF2D4D991D305F89', owner), - ('96E4509450D380DAC362FF8E295589128A1F1CE55885D20D89C27BA2A9D00909', owner), - ('9783B5EE4492E9E891C655F1F48035959DAD453C0E623AF0FE7BF2C0A57885E3', owner), - ('97A51A094444620DF38CD8C6512CAC909A75FD437AE1E4D22929807661238127', owner), - ('97A8C5BA11D61FEFBB5D6A05DA4E15BA472DC4C6CD4972FC1A035DE321342FE4', owner), - ('992820E6EC8C41DAAE4BD8AB48F58268E943A670D35CA5E2BDCD3E7C4C94A072', owner), - ('992D359AA7A5F789D268B94C11B9485A6B1CE64362B0EDB4441CCC187C39647B', owner), - ('9954A1A99D55E8B189AB1BCA414B91F6A017191F6C40A86B6F3EF368DD860031', owner), - ('9998D363C491BE16BD74BA10B94D9291001611736FDCA643A36664BC0F315A42', owner), - ('9BAF4F76D76BF5D6A897BFBD5F429BA14D04E08B48C3EE8D76930A828FFF3891', owner), - ('9C259FCB301D5FC7397ED5759963E0EF6B36E42057FD73046E6BD08B149F751C', owner), - ('9D00AE4CD47A41C783DC48F342C076C2C16F3413F4D2DF50D181CA3BB5AD859D', owner), - ('9DD2DCB72F5E741627F2E9E03AB18503A3403CF6A904A479A4DB05D97E2250A9', owner), - ('9E4A69173161682E55FDE8FEF560EB88EC1FFEDCAF04001F66C0CAF707B2B734', owner), - ('9ED33F0FBC180BC032F8909CA2C4AB3418EDC33A45A50D2521A3B5876AA3EA2C', owner), - ('9F1863ED5717C394B42EF10A6607B144A65BA11FB6579DF94B8EB2F0C4CD60C1', owner), - ('9FA4D5023FD43ECAFF4200BA7E8D4353259D2B7E5E72B5096EFF8027D66D1043', owner), - ('A4D978B7C4BDA15435D508F8B9592EC2A5ADFB12EA7BAD146A35ECB53094642F', owner), - ('A6B5151F3655D3A2AF0D472759796BE4A4200E5495A7D869754C4848857408A7', owner), - ('A7F32F508D4EB0FEAD9A087EF94ED1BA0AEC5DE6F7EF6FF0A62B93BEDF5D458D', owner), - ('A924D3CAD6DA42B7399B96A095A06F18F6B1ABA5B873B0D5F3A0EE2173B48B6C', owner), - ('AD3BE589C0474E97DE5BB2BF33534948B76BB80376DFDC58B1FED767B5A15BFC', owner), - ('AD6826E1946D26D3EAF3685C88D97D85DE3B4DCB3D0EE2AE81C70560D13C5720', owner), - ('AEEBAE3151271273ED95AA2E671139ED31A98567303A332298F83709A9D55AA1', owner), - ('AFE2030AFB7D2CDA13F9FA333A02E34F6751AFEC11B010DBCD441FDF4C4002B3', owner), - ('B3E506340FBF6B5786973393079F24B66BA46507E35E911DB0362A2ACDE97049', owner), - ('B54F1EE636631FAD68058D3B0937031AC1B90CCB17062A391CCA68AFDBE40D55', owner), - ('B8D6B5E7857B45830E017C7BE3D856ADEB97C7290EB0665A3D473A4BEB51DCF3', owner), - ('B8F078D983A24AC433216393883514CD932C33AF18E7DD70884C8235F4275736', owner), - ('B92AF298DC08049B78C77492D6551B710CD72AADA3D77BE54609E43278EF6E4D', owner), - ('B93F0699598F8B20FA0DACC12CFCFC1F2568793F6E779E04795E6D7C22530F75', owner), - ('B97A0889059C035FF1D54B6DB53B11B9766668D9F955247C028B2837D7A04CD9', owner), - ('BADFF5E4F0FEA711701CA8FB22E4C43821E31E210CF52D1D4F74DD50F1D039BC', owner), - ('BB01DA0333BB639C7E1C806DB0561DC98A5316F22FEF1090FB8D0BE46DAE499A', owner), - ('BB1DD16D530008636F232303A7A86F3DFF969F848815C0574B12C2D787FEC93F', owner), - ('BC75F910FF320F5CB5999E66BBD4034F4AE537A42FDFEF35161C5348E366E216', owner), - ('BC87A668E81966489CB508EE805183C19E6ACD24CF17799CA062D2E384DA0EA7', owner), - ('BDD01126E9D85710D3FE75AF1CC1702A29F081B4F6FDF6A2B2135C0297A9CEC5', owner), - ('BE435DF7CD28AA2A7C8DB4FC8173475B77E5ABF392F76B7C76FA3F698CB71A9A', owner), - ('BEF7663BE5EA4DBFD8686E24701E036F4C03FB7FCD67A6C566ED94CE09C44470', owner), - ('C2469759C1947E14F4B65F72A9F5B3AF8B6F6E727B68BB0D91385CBF42176A8A', owner), - ('C3505BF3EC10A51DACE417C76B8BD10939A065D1F34E75B8A3065EE31CC69B96', owner), - ('C3A99A460DA464A057C3586D83CEF5F4AE08B7103979ED8932742DF0ED530C66', owner), - ('C409BDAC4775ADD8DB92AA22B5B718FB8C94A1462C1FE9A416B95D8A3388C2FC', owner), - ('C42D11C70CCF5E8CF3FB91FDF21D884021AD836CA68ADF2CBB7995C10BF588D4', owner), - ('C452AB846073DF5ACE25CCA64D6B7A09D906308A1A65EB5240E3C4EBCAA9CC0C', owner), - ('C5D9D8A186E2C82D09AFAA2A6F7F2E73870D3E64F72C4E08EF67796A840F0FBD', owner), - ('C617C1A8B1EE2A811C28B5A81B4C83D7C98B5B0C27281D610207EBE692C2967F', owner), - ('C69D64A5B839E41BA16742527E17056A18CE3C276FD26E34901A1BC7D0E32219', owner), - ('C805603C4FA038776E42F263C604B49D96840322E1922D5606A9B0BBB5BFFE6F', owner), - ('C83CB13922AD99F560744675DD37CC94DCAD5A1FCBA6472FEE341171D939E884', owner), - ('C90F336617B8E7F983975413C997F10B73EB267FD8A10CB9E3BDBFC667ABDB8B', owner), - ('C9EC350406F26E559AFFB4030DE2EBDE5435054C35A998605B8FCF04972D8D55', owner), - ('CA171D614A8D7E121C93948CD0FE55D39981F9D11AA96E03450A415227C2C65B', owner), - ('CB340011AFEB0D74C4A588B36EBAA441961608E8D2FA80DCA8C13872C850796B', owner), - ('CB6B858B40D3A098765815B592C1514A49604FAFD60819DA88D7A76E9778FEF7', owner), - ('CC8EEC6EB9212CBF897A5ACE7E8ABEECE1079F1A6DEF0A789591CB1547F1F084', owner), - ('CE3BFABE59D67CE8AC8DFD4A16F7C43EF9C224513FBC655957D735FA29F540CE', owner), - ('CF13A243C1CD2E3C8CEB7E70100387CECBFB830525BBF9D0B70C79ADF3E84128', owner), - ('D063EC28F67EBA53F1642DBF7DFF33C6A32ADD869F6013FE162E2C32F1CBE56D', owner), - ('D372C0D0F4FDC9F52E9E1F23FC56EE72414A17F350D0CEA6C26A35A6C3217A13', owner), - ('D626157E1D6A718BC124AB8DA27CBB65072CA03A7B6B257DBDCBBD60F65EF3D1', owner), - ('D89A11D16C488DD4FBBC541D4B07FAF8670D660994488FE54B1FBFF2704E4288', owner), - ('D8CBEB9735F5672B367E4F96CDC74969615D17074AE96C724D42CE0216F8F3FA', owner), - ('D8D4E6DDF6E42D74A6A536EA62FD1217E4290B145C9E5C3695A31B42EFB5F5A4', owner), - ('D9668AB52785086786C134B5E4BDDBF72452813B6973229AB92AA1A54D201BF5', owner), - ('DA3560FD0C32B54C83D4F2FF869003D2089369ACF2C89608F8AFA7436BFA4655', owner), - ('DBAF9E056D3D5B38B68553304ABC88827EBC00F80CB9C7E197CDBC5822CD316C', owner), - ('DCCC3CE1C00EE4B0B10487D372A0FA47F5C26F57A359BE7B27801E144EACBAC4', owner), - ('DD59AF56084406E38C63FBE0850F30A0CD1277462A2192590FB05BC259E61273', owner), - ('DF02AAB48387A9E1D4C65228089CB6ABE196C8F4B396C7E4BBC395DE136977F6', owner), - ('DF91AC85A94FCD0CFB8155BD7CBEFAAC14B8C5EE7397FE2CC85984459E2EA14E', owner), - ('E051B788ECBAEDA53046C70E6AF6058F95222C046157B8C4C1B9C2CFC65F46E5', owner), - ('E19DAE83C02E6F281358D4EBD11D7723B4F5EA0E357907D5443DECC5F93C1E9D', owner), - ('E24B315A551671483D8B9073B32DE11B4DE1EB2EAB211AFD2D9C319FF55E08D0', owner), - ('E36DFC719D2114C2E39AEA88849E2845AB326F6F7FE74E0E539B7E54D81F3631', owner), - ('E39891F48BBCC593B8ED86CE82CE666FC1145B9FCBFD2B07BAD0A89BF4C7BFBF', owner), - ('E6856F137F79992DC94FA2F43297EC32D2D9A76F7BE66114C6A13EFC3BCDF5C8', owner), - ('E6CA68E94146629AF03F69C2F86E6BEF62F930B37C6FBCC878B78DF98C0334E5', owner), - ('E7681F153121EA1E67F74BBCB0CDC5E502702C1B8CC55FB65D702DFBA948B5F4', owner), - ('E7C20B3AB481EC885501ECA5293781D84B5A1AC24F88266B5270E7ECB4AA2538', owner), - ('E800395DBE0E045781E8005178B4BAF5A257F06E159121A67C595F6AE22506FD', owner), - ('E92C22EB3B5642D65C1EC2CAF247D2594738EEBB7FB3841A44956F59E2B0D1FA', owner), - ('EAFF8C85C208BA4D5B6B8046F5D6081747D779BADA7768E649D047FF9B1F660C', owner), - ('EE83A566496109A74F6AC6E410DF00BB29A290E0021516AE3B8A23288E7E2E72', owner), - ('EED7E0EFF2ED559E2A79EE361F9962AF3B1E999131E30BB7FD07546FAE0A7267', owner), - ('F1863EC8B7F43F94AD14FB0B8B4A69497A8C65ECBC2A55E0BB420E772B8CDC91', owner), - ('F1B4F6513B0D544A688D13ADC291EFA8C59F420CA5DCB23E0B5A06FA7E0D083D', owner), - ('F277AF4F9BDC918AE89FA35CC1B34E34984C04AE9765322C3CB049574D36509C', owner), - ('F2A16D35B554694187A70D40CA682959F4F35C2CE0EAB8FD64F7AC2AB9F5C24A', owner), - ('F31FD461C5E99510403FC97C1DA2D8A9CBE270597D32BADF8FD66B77495F8D94', owner), - ('F48E6DD8718E953B60A24F2CBEA60A9521DEAE67DB25425B7D3ACE3C517DD9B7', owner), - ('F52F83A3FA9CFBD6920F722824DBE4034534D25B8507246B3B957DAC6E1BCE7A', owner), - ('FDDD6E3D29EA84C7743DAD4A1BDBC700B5FEC1B391F932409086ACC71DD6DBD8', owner), - ('FE63A84F782CC9D3FCF2CCF9FC11FBD03760878758D26285ED12669BDC6E6D01', owner), - ('FECFB232D12E994B6D485D2C7167728AA5525984AD5CA61E7516221F079A1436', owner) + ("0257FF710F2A16E489B37493C07604A7CDA96129D8A8FD68D2B6AF633904315D", owner), + ("02E6216ACAEF6401401FA555ECBED940B1A5F2569AED92956137AE58482EF1B7", owner), + ("03F64A29948A88BEFFDB035E0B09A7370CCF0CD9CE6BCF8E640C2107318FAB87", owner), + ("05D87E15713454616F5B0ED7849AB5C1712AB84F02349478EC2A38F970C01489", owner), + ("06EB5BADD26E4FAE65F9A42358DEEF7C18E52CC05FBB7FC76776E69D1B982A14", owner), + ("075EEA060589548BA060B2FEED10DA3C20C7FE9B17CD026B94E8A683B8115238", owner), + ("07E6C6A858646FB1EFC67903FE28B116011F2367FE92E6BE2B36999EFF39D09E", owner), + ("08BB2289E9E91B4D20FF3F1562516AB07E979B2C6CEFE2AB70C6DFC1199F8DA5", owner), + ("0928F0408BF725E61D67D87138A8EEBC52962D2847F16E3587163B160E41B6AD", owner), + ("09DF5F4E511208EC78B96D12D08125FDB603868DE39F6F72927852599B659C26", owner), + ("09F98AA90F85198C0D73F89BA77E87EC6F596C491350FB8F8BBA80A62FBB914B", owner), + ("0A75EA0B1D70EAA4D3F374246DB54FC7B43E7F596A353309B9C36B4FD975725E", owner), + ("0BBB4392DAAC7AB89B30A4AC657531B97BFAAB04F90B0DAFE5F9B6EB90A06374", owner), + ("0C189339762DF336AB3DD006A463DF715A39CFB0F492465C600E6C6BD7BD898C", owner), + ("0C51D7906FC4931149765DA88682426B2CFE9E6AA4F27253EAB400111432E3A7", owner), + ("0CE02100F67C7EF85F4EED368F02BF7092380A3C23CA91FD7F19430D94B00C19", owner), + ("0D0DBECA6F29ECA06F331A7D72E4884B12097FB348983A2A14A0D73F4F10140F", owner), + ("0DC24C75EB1AEF56B9F13AB9DE60E2ECA1C4510034E290BBB36CF60A549B234C", owner), + ("0DC9F3FB99962148C3CA833632758D3ED4FC8D0B0007B95B31E6528F2ACD5BFC", owner), + ("0FA3A29AD05130D7FE5BF4D2596563CDED1D874096AACC181069932A2E49519A", owner), + ("106FACEACFECFD4E303B74F480A08098E2D0802B936F8EC774CE21F31686689C", owner), + ("10D45FCBA396AEF3153EE8F6ECAE58AFE8476A280A2026FC71F6217DCF49BA2F", owner), + ("147730B42F11FE493FE902B6251E97CD2B6F34D36AF59330F11D02A42F940D07", owner), + ("148FE18F715A9FCFE1A444CE0FFF7F85869EB422330DC04B314C0F295D6DA79E", owner), + ("174E3A0B5B43C6A607BBD3404F05341E3DCF396267CE94F8B50E2E23A9DA920C", owner), + ("18333429FF0562ED9F97033E1148DCEEE52DBE2E496D5410B5CFD6C864D2D10F", owner), + ("1AEC84B84B6C65A51220A9BE7181965230210D62D6D33C48999C6B295A2B0A06", owner), + ("1B909115A8D473E51328A87823BD621CE655DFAE54FA2BFA72FDC0298611D6B8", owner), + ("1CB4DCCAF2C812CFA7B4938E1371FE2B96910FE407216FD95428672D6C7E7316", owner), + ("1D8B58C1FDB8DA8B33CCEE1E5F973AF734D90EF317E33F5DB1573C2BA088A80C", owner), + ("1F16078CCE009DF62EDB9E7170E66CAAE670BCE71B8F92D38280C56AA372031D", owner), + ("1F179186EFDF5EF2DE018245BA0EAE8134868601BA0D35FF3D9865C1537CED93", owner), + ("2679650FE341F2CF1EA883460B3556AAAF77A70D6B8DC484C9301D1B746CF7B5", owner), + ("270C84B29D86F16312B06AAAE4EBB8DFF8DE7D080D825B8839FF1766274EFF47", owner), + ("29C6EB52B43C3AA18B2CD8ED6EA8607CEF3CFAE1BAFE1165755CF2E614844A44", owner), + ("29CCA4544EA330D61591C784695C149C6B040022AC7B5B89CBD72800D10840EA", owner), + ("2B2298EAA26B9DC4A4558AE92E7BB0E4F85CF34BF848FDF636C0C11FBEC49897", owner), + ("2B99CF26422E92FE365FBF4BC30D27086C9EE14B7A6FFF44FB2F6B9001699939", owner), + ("2BBF2CA7B8F1D91F27EE52B6FB2A5DD049B85A2B9B529C5D6662068104B055F8", owner), + ("2C73D93325BA6DCBE589D4A4C63C5B935559EF92FBF050ED50C4E2085206F17D", owner), + ("2DCF8E8D817023D1E8E1451A3D68D6EC30D9BED94CBCB87F19DDC1CC0116AC1A", owner), + ("2E70916786A6F773511FA7181FAB0F1D70B557C6322EA923B2A8D3B92B51AF7D", owner), + ("306628FA5477305728BA4A467DE7D0387A54F569D3769FCE5E75EC89D28D1593", owner), + ("311A2AC55B50C09B30B3CC93B994A119153EEEAC54EF892FC447BBBD96101AA1", owner), + ("32AD3296829BC46DCFAC5EDDCB9DBF2C1EED5C11F83B2210CF9C6E60C798D4A7", owner), + ("32F5940CA29DD812A2C145E6FC89646628FFCC7C7A42CAE512337D8D29C40BBD", owner), + ("340DA32B58331C8E2B561BAF300CA9DFD6B91CD2270EE0E2A34958B1C6259E85", owner), + ("3608EDBAF5AD0F41A414A1777ABF2FAF5E670334675EC3995E6935829E0CAAD2", owner), + ("362ED31D20B1E00392281231A96F0A0ACFDE02618953E695C9EF2EB0BAC37550", owner), + ("363384D14D1F2E0B7815626484C459AD57A318EF4396266048D058C5A19BBF76", owner), + ("367A31E5838831AD2C074647886A6CDFF217E6B1BA910BFF85DC7A87AE9B5E98", owner), + ("3765D769C05BF98B427B3511903B2137E8A49B6F859D0AF159ED6A86786AA634", owner), + ("37A480374DAF6202CE790C318A2BB8AA3797311261160A8E30558B7DEA78C7A6", owner), + ("3841D221368D1583D75C0A02E62160394D6C4E0A6760B6F607B90362BC855B02", owner), + ("386D695CDF2D4576E01BCACCF5E49E78DA51AF9955C0B8FA7606373B007994B3", owner), + ("39DBC2288EF44B5F95332CB777E31103E840DBA680634AA806F5C9B100061802", owner), + ("3A4F74BEAFAE2B9383AD8215D233A6CF3D057FB3C7E213E897BEEF4255FAEE9D", owner), + ("3A91F0F9E5287FA2994C7D930B2C1A5EE14CE8E1C8304AE495ADC58CC4453C0C", owner), + ("3AE76C45CA70E9180C1559981F42622DD251BCA1FBE6B901C52EC11673B03514", owner), + ("3B0287533E0CC3D0EC1AA823CBF0A941AAD8721579D1C499802DD1C3A636B8A9", owner), + ("3BE8E7EB348D35C1928F19C769846788991641D1F6CF09514CA10269934F7359", owner), + ("3E3926F0B8A15AD5A14167BB647A843C3D4321E35DBC44DCE8C837417F2D28B0", owner), + ("3ECE27CBB3EC4438CCE523B927C4F05FDC5C593A3766DB984C5E437A3FF6A16B", owner), + ("3FCE9B9FDF3EF09D5452B0F95EE481C2B7F06D743A737971558E70136ACE3E73", owner), + ("400AC66D59B7B094A9E30B01A6BD013AFF1D30570F83E7592F421DBE5FF4BA8F", owner), + ("408B8B3DF5ABB043521A493525023175AB1261B1DE21064D6BF247CE142153B9", owner), + ("4185821F6DAB5BA8347B78A22B5F9A0A7570CA5C93A74D478A793D83BAC49805", owner), + ("41D1EEB177C0324E17DD6557F384E532DE0CF51A019A446B01EFB351BC259D77", owner), + ("4397DACA839E7F63077CB50C92DF43BC2D2FB2A8F59F26FC7A0E4BD4D9751692", owner), + ("45876B4DD861D45B3A94800774027A5DB45A48B2A729410908B6412F8A87E95D", owner), + ("45C7C8AE750ACFBB48FC37527D6412DD644DAED8913CCD8A24C94D856967DF8E", owner), + ("4667BF250CD7C1A06B8474C613CDB1DF648A7F58736FBF57D05D6F755DAB67F4", owner), + ("47CC086127E2069A86E03A6BEF2CD410F8C55A6D6BDB362168C31B2CE32A5ADF", owner), + ("47FF1B63B140B6FC04ED79131331E651DA5B2E2F170F5DAEF4153DC2FBC532B1", owner), + ("495300790E6C9BF2510DABA59DB3D57E9D2B85D7D7640434EC75BAA3851C74E5", owner), + ("4B8668A5D465BCDD9000AA8DFCFF42044FCBD0AECE32FC7011A83E9160E89F09", owner), + ("518831FE7382B514D03E15C621228B8AB65479BD0CBFA3C5C1D0F48D9C306135", owner), + ("5391C3A2FB112102A6AA1EDC25AE77E19F5D6F09CD09EEB2509922BFCD5992EA", owner), + ("540801DD345DC1C33EF431B35BF4C0E68BD319B577B9ABE1A9CFF1CBC39F548F", owner), + ("55B99B0DE53DBCFE485AA9C737CF3FB616EF3D91FAB599AA7CAB19EDA763B5BA", owner), + ("57E6913AFACC5222BD76CDAF31F8ED88895464255374EF097A82D7F59AD39596", owner), + ("5890FA227121C76D90ED9E63C87E3A6533EEA0F6F0A1A23F1FC445139BC6BCDF", owner), + ("58FB941AEF95A25943B3FB5F2510A0DF3FE44C58C95E0AB80487297568AB9771", owner), + ("5AE949EA8855EB93E439DBC65BDA2E42852C2FDF6789FA146736E3C3410F2B5C", owner), + ("5B248E913D71853D3DA5AEDD8D9A4BC57A917126573817FB5FCB2D86A2F1C886", owner), + ("5C5805196A85E93789457017D4F9EB6828B97C41CB9BA6D3DC1FCC115F527A55", owner), + ("5D1E9ACBBB4A7D024B6852DF025970E2CED66FF622EE019CD0ED7FD841CCAD02", owner), + ("61341E07697978220EA61E85DCD2421343F2C1BF35CC5B8D0AD2F0226F391479", owner), + ("61CEC4A377BF5902C0FEAEE37034BF97D5BC6E0615E23A1CDFBAE6E3F5FB3CFD", owner), + ("631F0857B41845362C90C6980B4B10C4B628E23DBE24B6E96C128AE3DCB0D5AC", owner), + ("64575BD912789A2E14AD56F6341F52AF6BF80CF94400785975E9F04E2D64D745", owner), + ("65B2E7CC18D903C331DF1152DF73CA0DC932D29F17997481C56F3087B2DD3147", owner), + ("65F3C0A01B8402D362B9722E98F75E5E991E6C186E934F7B2B2E6BE6DEC800EC", owner), + ("66AA13A0EDC219384D9C425D3927E6ED4A5D1940C5E7CD4DAC88F5770103F2F1", owner), + ("6873D2F61C29BD52E954EEFF5977AA8367439997811A62FF212C948133C68D97", owner), + ("68EE4632C7BE1C66C83E89DD93EAEE1294159ABF45B4C2C72D7DC7499AA2A043", owner), + ("6B1D138078E4418AA68DEB7BB35E066092CF479EEB8CE4CD12E7D072CCB42F66", owner), + ("6C8854478DD559E29351B826C06CB8BFEF2B94AD3538358772D193F82ED1CA11", owner), + ("6DBBEAD23E8C860CF8B47F74FBFCA5204DE3E28B881313BB1D1ECCDC4747934E", owner), + ("6DEAD13257DFC3CCC6A4B37016BA91755FE9E0EC1F415030942E5ABC47F07C88", owner), + ("6EFEFE0B5B01478B7B944C10D3A8ACA2CCA4208888E2059F8A06CB5824D7BAB0", owner), + ("6F1428FF71C9DB0ED5AF1F2E7BBFCBAB647CC265DDF5B293CDB626F50A3A785E", owner), + ("70A1450AF2AD395569AD0AFEB1D9C125324EE90AEC39C258880134D4892D51AB", owner), + ("71F2906FD222497E54A34662AB2497FCC81020770FF51368E9E3D9BFCBFD6375", owner), + ("726B3EB654046A30F3F83D9B96CE03F670E9A806D1708A0371E62DC49D2C23C1", owner), + ("72C26F827CEB92989798961BC6AE748D141E05D3EBCFB65D9041B266C920BE82", owner), + ("72E0BD1867CF5D9D56AB158ADF3BDDBC82BF32A8D8AA1D8C5E2F6DF29428D6D8", owner), + ("77DD190FA30D88FF5E3B011A0AE61E6209780C130B535ECB87E6F0888A0B6B2F", owner), + ("781764102188A8B4B173D4A8F5EC94D828647156097F99357A581E624B377509", owner), + ("7827AF99362CFAF0717DADE4B1BFE0438AD171C15ADDC248B75BF8CAA44BB2C5", owner), + ("788383A4C733BB87D2BF51673DC73E92DF15AB7D51DC715627AE77686D8D23BC", owner), + ("78B4EDCAABC8D9093E20E217802CAEB4F09E23A3394C4ACC6E87E8F35395310F", owner), + ("7BC9CB5463CE0F011FB5085EB8BA77D1ACD283C43F4A57603CC113F22CEBC579", owner), + ("7EAC80A915C84CD4AFEC638904D94EB168A8557951A4D539B0713028552B6B8C", owner), + ("7F49CCB309323B1C7AB11C93C955B8C744F0A2B75C311F495E18906070500027", owner), + ("804E354C6368BB27A90FAE8E498A57052B293418259A019C4F53A2007254490F", owner), + ("80B4D96931BF0D02FD91A61E19D14F1DA452E66DB2408CA8604D411F92659F0A", owner), + ("81A8B2C9751AEB1FABA7DBDE5EE9691DC0EAEE2A31C38B1491A8146756A6B770", owner), + ("81A8B965BB84D3876B9429A95481CC955318CFAA1412D808C8A33BFD33FFF0E4", owner), + ("81D8FB4C9E2E7A8225656B4B8273B7CBA4B03EF2E9EB20E0A0291624ECA1BA86", owner), + ("82ACBA48D5236CCFF7659AFC14594DEE902BD6082EF1A30A0B9B508628CF34F4", owner), + ("82DB3BCEB4F60843CE9D97C3D187CD9B5941CD3DE8100E586F2BDA5637575F67", owner), + ("835881F2A5572D7059B5C8635018552892E945626F115FC9CA07ACF7BDE857A4", owner), + ("894D7839368F3298CC915AE8742EF330D7A26699F459478CF22C2B6BB2850166", owner), + ("895A9785F617CA1D7ED44FC1A1470B71F3F1223862D9FF9DCC3AE2DF92163DAF", owner), + ("89F3D1F6E485C334CD059D0995E3CDFDC00571B1849854847A44DC5548E2DCFB", owner), + ("8AD64859F195B5F58DAFAA940B6A6167ACD67A886E8F469364177221C55945B9", owner), + ("8BF434B49E00CCF71502A2CD900865CB01EC3B3DA03C35BE505FDF7BD563F521", owner), + ("8C0349D708571AE5AA21C11363482332073297D868F29058916529EFC520EF70", owner), + ("8D8EA289CFE70A1C07AB7365CB28EE51EDD33CF2506DE888FBADD60EBF80481C", owner), + ("8D93D60C691959651476E5DC464BE12A85FA5280B6F524D4A1C3FCC9D048CFAD", owner), + ("8E53EFDC15F852CEE5A6E92931BC42E6163CD30FF649CCA7E87252C3A459960B", owner), + ("9063F5FBC5E57AB6DE6C9488146020E172B176D5AB57D4C89F0F600E17FE2DE2", owner), + ("90FBE70E69D633408D3E170C6832DBB2D209E0272527DFB63D49D29572A6F44C", owner), + ("91656AA4EF493B3824A0B7263248E4E2D657A5C8488D880CB65B01730932FB53", owner), + ("91971C1497BF8E5BC68439ACC48D63EBB8FAABFD764DCBE82F3BA977CAC8CF6A", owner), + ("939AEEF4F5FA51E23340C3F2E49048CE8872526AFDF752C3A7F3A3F2BC9F6049", owner), + ("947078F97C6196968C3AE99C9A5D58667E86882CF6C8C9D58967A496BB7AF43C", owner), + ("95049F0E4137C790B0D2767195E56F73807D123ADCF8F6E7BF2D4D991D305F89", owner), + ("96E4509450D380DAC362FF8E295589128A1F1CE55885D20D89C27BA2A9D00909", owner), + ("9783B5EE4492E9E891C655F1F48035959DAD453C0E623AF0FE7BF2C0A57885E3", owner), + ("97A51A094444620DF38CD8C6512CAC909A75FD437AE1E4D22929807661238127", owner), + ("97A8C5BA11D61FEFBB5D6A05DA4E15BA472DC4C6CD4972FC1A035DE321342FE4", owner), + ("992820E6EC8C41DAAE4BD8AB48F58268E943A670D35CA5E2BDCD3E7C4C94A072", owner), + ("992D359AA7A5F789D268B94C11B9485A6B1CE64362B0EDB4441CCC187C39647B", owner), + ("9954A1A99D55E8B189AB1BCA414B91F6A017191F6C40A86B6F3EF368DD860031", owner), + ("9998D363C491BE16BD74BA10B94D9291001611736FDCA643A36664BC0F315A42", owner), + ("9BAF4F76D76BF5D6A897BFBD5F429BA14D04E08B48C3EE8D76930A828FFF3891", owner), + ("9C259FCB301D5FC7397ED5759963E0EF6B36E42057FD73046E6BD08B149F751C", owner), + ("9D00AE4CD47A41C783DC48F342C076C2C16F3413F4D2DF50D181CA3BB5AD859D", owner), + ("9DD2DCB72F5E741627F2E9E03AB18503A3403CF6A904A479A4DB05D97E2250A9", owner), + ("9E4A69173161682E55FDE8FEF560EB88EC1FFEDCAF04001F66C0CAF707B2B734", owner), + ("9ED33F0FBC180BC032F8909CA2C4AB3418EDC33A45A50D2521A3B5876AA3EA2C", owner), + ("9F1863ED5717C394B42EF10A6607B144A65BA11FB6579DF94B8EB2F0C4CD60C1", owner), + ("9FA4D5023FD43ECAFF4200BA7E8D4353259D2B7E5E72B5096EFF8027D66D1043", owner), + ("A4D978B7C4BDA15435D508F8B9592EC2A5ADFB12EA7BAD146A35ECB53094642F", owner), + ("A6B5151F3655D3A2AF0D472759796BE4A4200E5495A7D869754C4848857408A7", owner), + ("A7F32F508D4EB0FEAD9A087EF94ED1BA0AEC5DE6F7EF6FF0A62B93BEDF5D458D", owner), + ("A924D3CAD6DA42B7399B96A095A06F18F6B1ABA5B873B0D5F3A0EE2173B48B6C", owner), + ("AD3BE589C0474E97DE5BB2BF33534948B76BB80376DFDC58B1FED767B5A15BFC", owner), + ("AD6826E1946D26D3EAF3685C88D97D85DE3B4DCB3D0EE2AE81C70560D13C5720", owner), + ("AEEBAE3151271273ED95AA2E671139ED31A98567303A332298F83709A9D55AA1", owner), + ("AFE2030AFB7D2CDA13F9FA333A02E34F6751AFEC11B010DBCD441FDF4C4002B3", owner), + ("B3E506340FBF6B5786973393079F24B66BA46507E35E911DB0362A2ACDE97049", owner), + ("B54F1EE636631FAD68058D3B0937031AC1B90CCB17062A391CCA68AFDBE40D55", owner), + ("B8D6B5E7857B45830E017C7BE3D856ADEB97C7290EB0665A3D473A4BEB51DCF3", owner), + ("B8F078D983A24AC433216393883514CD932C33AF18E7DD70884C8235F4275736", owner), + ("B92AF298DC08049B78C77492D6551B710CD72AADA3D77BE54609E43278EF6E4D", owner), + ("B93F0699598F8B20FA0DACC12CFCFC1F2568793F6E779E04795E6D7C22530F75", owner), + ("B97A0889059C035FF1D54B6DB53B11B9766668D9F955247C028B2837D7A04CD9", owner), + ("BADFF5E4F0FEA711701CA8FB22E4C43821E31E210CF52D1D4F74DD50F1D039BC", owner), + ("BB01DA0333BB639C7E1C806DB0561DC98A5316F22FEF1090FB8D0BE46DAE499A", owner), + ("BB1DD16D530008636F232303A7A86F3DFF969F848815C0574B12C2D787FEC93F", owner), + ("BC75F910FF320F5CB5999E66BBD4034F4AE537A42FDFEF35161C5348E366E216", owner), + ("BC87A668E81966489CB508EE805183C19E6ACD24CF17799CA062D2E384DA0EA7", owner), + ("BDD01126E9D85710D3FE75AF1CC1702A29F081B4F6FDF6A2B2135C0297A9CEC5", owner), + ("BE435DF7CD28AA2A7C8DB4FC8173475B77E5ABF392F76B7C76FA3F698CB71A9A", owner), + ("BEF7663BE5EA4DBFD8686E24701E036F4C03FB7FCD67A6C566ED94CE09C44470", owner), + ("C2469759C1947E14F4B65F72A9F5B3AF8B6F6E727B68BB0D91385CBF42176A8A", owner), + ("C3505BF3EC10A51DACE417C76B8BD10939A065D1F34E75B8A3065EE31CC69B96", owner), + ("C3A99A460DA464A057C3586D83CEF5F4AE08B7103979ED8932742DF0ED530C66", owner), + ("C409BDAC4775ADD8DB92AA22B5B718FB8C94A1462C1FE9A416B95D8A3388C2FC", owner), + ("C42D11C70CCF5E8CF3FB91FDF21D884021AD836CA68ADF2CBB7995C10BF588D4", owner), + ("C452AB846073DF5ACE25CCA64D6B7A09D906308A1A65EB5240E3C4EBCAA9CC0C", owner), + ("C5D9D8A186E2C82D09AFAA2A6F7F2E73870D3E64F72C4E08EF67796A840F0FBD", owner), + ("C617C1A8B1EE2A811C28B5A81B4C83D7C98B5B0C27281D610207EBE692C2967F", owner), + ("C69D64A5B839E41BA16742527E17056A18CE3C276FD26E34901A1BC7D0E32219", owner), + ("C805603C4FA038776E42F263C604B49D96840322E1922D5606A9B0BBB5BFFE6F", owner), + ("C83CB13922AD99F560744675DD37CC94DCAD5A1FCBA6472FEE341171D939E884", owner), + ("C90F336617B8E7F983975413C997F10B73EB267FD8A10CB9E3BDBFC667ABDB8B", owner), + ("C9EC350406F26E559AFFB4030DE2EBDE5435054C35A998605B8FCF04972D8D55", owner), + ("CA171D614A8D7E121C93948CD0FE55D39981F9D11AA96E03450A415227C2C65B", owner), + ("CB340011AFEB0D74C4A588B36EBAA441961608E8D2FA80DCA8C13872C850796B", owner), + ("CB6B858B40D3A098765815B592C1514A49604FAFD60819DA88D7A76E9778FEF7", owner), + ("CC8EEC6EB9212CBF897A5ACE7E8ABEECE1079F1A6DEF0A789591CB1547F1F084", owner), + ("CE3BFABE59D67CE8AC8DFD4A16F7C43EF9C224513FBC655957D735FA29F540CE", owner), + ("CF13A243C1CD2E3C8CEB7E70100387CECBFB830525BBF9D0B70C79ADF3E84128", owner), + ("D063EC28F67EBA53F1642DBF7DFF33C6A32ADD869F6013FE162E2C32F1CBE56D", owner), + ("D372C0D0F4FDC9F52E9E1F23FC56EE72414A17F350D0CEA6C26A35A6C3217A13", owner), + ("D626157E1D6A718BC124AB8DA27CBB65072CA03A7B6B257DBDCBBD60F65EF3D1", owner), + ("D89A11D16C488DD4FBBC541D4B07FAF8670D660994488FE54B1FBFF2704E4288", owner), + ("D8CBEB9735F5672B367E4F96CDC74969615D17074AE96C724D42CE0216F8F3FA", owner), + ("D8D4E6DDF6E42D74A6A536EA62FD1217E4290B145C9E5C3695A31B42EFB5F5A4", owner), + ("D9668AB52785086786C134B5E4BDDBF72452813B6973229AB92AA1A54D201BF5", owner), + ("DA3560FD0C32B54C83D4F2FF869003D2089369ACF2C89608F8AFA7436BFA4655", owner), + ("DBAF9E056D3D5B38B68553304ABC88827EBC00F80CB9C7E197CDBC5822CD316C", owner), + ("DCCC3CE1C00EE4B0B10487D372A0FA47F5C26F57A359BE7B27801E144EACBAC4", owner), + ("DD59AF56084406E38C63FBE0850F30A0CD1277462A2192590FB05BC259E61273", owner), + ("DF02AAB48387A9E1D4C65228089CB6ABE196C8F4B396C7E4BBC395DE136977F6", owner), + ("DF91AC85A94FCD0CFB8155BD7CBEFAAC14B8C5EE7397FE2CC85984459E2EA14E", owner), + ("E051B788ECBAEDA53046C70E6AF6058F95222C046157B8C4C1B9C2CFC65F46E5", owner), + ("E19DAE83C02E6F281358D4EBD11D7723B4F5EA0E357907D5443DECC5F93C1E9D", owner), + ("E24B315A551671483D8B9073B32DE11B4DE1EB2EAB211AFD2D9C319FF55E08D0", owner), + ("E36DFC719D2114C2E39AEA88849E2845AB326F6F7FE74E0E539B7E54D81F3631", owner), + ("E39891F48BBCC593B8ED86CE82CE666FC1145B9FCBFD2B07BAD0A89BF4C7BFBF", owner), + ("E6856F137F79992DC94FA2F43297EC32D2D9A76F7BE66114C6A13EFC3BCDF5C8", owner), + ("E6CA68E94146629AF03F69C2F86E6BEF62F930B37C6FBCC878B78DF98C0334E5", owner), + ("E7681F153121EA1E67F74BBCB0CDC5E502702C1B8CC55FB65D702DFBA948B5F4", owner), + ("E7C20B3AB481EC885501ECA5293781D84B5A1AC24F88266B5270E7ECB4AA2538", owner), + ("E800395DBE0E045781E8005178B4BAF5A257F06E159121A67C595F6AE22506FD", owner), + ("E92C22EB3B5642D65C1EC2CAF247D2594738EEBB7FB3841A44956F59E2B0D1FA", owner), + ("EAFF8C85C208BA4D5B6B8046F5D6081747D779BADA7768E649D047FF9B1F660C", owner), + ("EE83A566496109A74F6AC6E410DF00BB29A290E0021516AE3B8A23288E7E2E72", owner), + ("EED7E0EFF2ED559E2A79EE361F9962AF3B1E999131E30BB7FD07546FAE0A7267", owner), + ("F1863EC8B7F43F94AD14FB0B8B4A69497A8C65ECBC2A55E0BB420E772B8CDC91", owner), + ("F1B4F6513B0D544A688D13ADC291EFA8C59F420CA5DCB23E0B5A06FA7E0D083D", owner), + ("F277AF4F9BDC918AE89FA35CC1B34E34984C04AE9765322C3CB049574D36509C", owner), + ("F2A16D35B554694187A70D40CA682959F4F35C2CE0EAB8FD64F7AC2AB9F5C24A", owner), + ("F31FD461C5E99510403FC97C1DA2D8A9CBE270597D32BADF8FD66B77495F8D94", owner), + ("F48E6DD8718E953B60A24F2CBEA60A9521DEAE67DB25425B7D3ACE3C517DD9B7", owner), + ("F52F83A3FA9CFBD6920F722824DBE4034534D25B8507246B3B957DAC6E1BCE7A", owner), + ("FDDD6E3D29EA84C7743DAD4A1BDBC700B5FEC1B391F932409086ACC71DD6DBD8", owner), + ("FE63A84F782CC9D3FCF2CCF9FC11FBD03760878758D26285ED12669BDC6E6D01", owner), + ("FECFB232D12E994B6D485D2C7167728AA5525984AD5CA61E7516221F079A1436", owner), ] canonical_hashes_esl = sha256_esl_builder(canonical_hashes) expected_canonical_esd = EfiSignatureDatabase(esl_list=[canonical_hashes_esl, cert2_esl, cert1_esl]) @@ -622,27 +618,14 @@ def BootHoleData(): def MixedCertsData(): """Returns a tuple of (rawData, expectedDupes, expectedCanonical) for a mix of unsorted certs with dupes""" - owner = '77fa9abd-0359-4d32-bd60-28f4e78f784b' + owner = "77fa9abd-0359-4d32-bd60-28f4e78f784b" - esls = [ - x509_esl_builder([(DEBIAN_CERT, owner)]), - x509_esl_builder([(UBUNTU_CERT, owner)]) - ] + esls = [x509_esl_builder([(DEBIAN_CERT, owner)]), x509_esl_builder([(UBUNTU_CERT, owner)])] - input = [ - esls[1], - esls[0], - esls[1], - esls[0], - esls[1] - ] + input = [esls[1], esls[0], esls[1], esls[0], esls[1]] esd = EfiSignatureDatabase(esl_list=input) - dupes = [ - esls[0], - esls[1], - esls[1] - ] + dupes = [esls[0], esls[1], esls[1]] expected_dupes_esd = EfiSignatureDatabase(esl_list=dupes) canonical = [ @@ -655,7 +638,6 @@ def MixedCertsData(): class AuthVarSupportLibraryUnitTests(unittest.TestCase): - def test_print(self): esd = basicEfiSignatureDatabase() with io.StringIO() as f: @@ -703,7 +685,7 @@ def test_EfiSignatureList_Sort_and_Deduplication_x509(self): [(DEBIAN_CERT, owner)], # expected duplicates [], - ) + ), ] for subTest in sub_test_list: @@ -719,7 +701,6 @@ def test_EfiSignatureList_Sort_and_Deduplication_x509(self): self.assertEqual(testEsl.encode(), expected_sort_esl.encode()) def test_EfiSignatureList_Sort_and_Deduplication_sha256(self): - owner1 = uuid.uuid4().hex owner2 = uuid.uuid4().hex @@ -828,7 +809,7 @@ def test_EfiSignatureList_Sort_and_Deduplication_sha256(self): (HASHSTR[1], owner1), (HASHSTR[2], owner1), (HASHSTR[1], owner1), - (HASHSTR[2], owner1) + (HASHSTR[2], owner1), ], # expected after sort [ @@ -900,7 +881,6 @@ def test_EfiSignatureDatabase_Sort_and_Deduplication(self): for sub_test in sub_test_list: (testName, (Esd, expected_dupes_esd, expected_canonical_esd)) = sub_test with self.subTest(msg=testName): - (output_canonical_esd, output_dupes_esd) = Esd.get_canonical_and_dupes() if VERBOSE: @@ -918,7 +898,6 @@ def test_EfiSignatureDatabase_Sort_and_Deduplication(self): class EfiVariableAuthenticatedTests(unittest.TestCase): - def build_test_authenticated_variable(self, payload): original_name = "MockVariable" guid = "4FCBCF26-5148-4713-982C-692E0DAD2F2A" @@ -960,7 +939,6 @@ def test_EfiVariableAuthentication2_load_from_file(self): self.assertEqual(Output.getvalue(), DbxIo.getvalue()) def test_creating_EfiVariableAuthentication2_variable(self): - payload = b"Hello UEFI" auth_variable = self.build_test_authenticated_variable(payload) @@ -975,27 +953,19 @@ def test_creating_EfiVariableAuthentication2_variable(self): self.assertTrue("EfiTime" in output) self.assertTrue("SignedData" in output) self.assertTrue("WIN_CERTIFICATE" in output) - self.assertTrue(payload.decode('ascii') in output) + self.assertTrue(payload.decode("ascii") in output) class EfiTimeTest(unittest.TestCase): """Test the EfiTime class""" def test_EfiTime_basic_usage(self): - test_data = [ - ( - [1970, 1, 1, 0, 0, 0], - b"\xB2\x07\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - ), - ( - [2022, 12, 5, 12, 33, 5], - b"\xe6\x07\x0c\x05\x0c\x21\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00" - ) + ([1970, 1, 1, 0, 0, 0], b"\xb2\x07\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), + ([2022, 12, 5, 12, 33, 5], b"\xe6\x07\x0c\x05\x0c\x21\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00"), ] for time_array, expected_bytes in test_data: - byte_stream = io.BytesIO() year, month, day, hour, minute, second = time_array @@ -1014,5 +984,5 @@ def test_EfiTime_basic_usage(self): self.assertEqual(efi_time.encode(), efi_time2.encode()) -#if __name__ == "__main__": +# if __name__ == "__main__": # unittest.main() diff --git a/tests.unit/test_bmp_object.py b/tests.unit/test_bmp_object.py index 075271cc..aab0cbd2 100644 --- a/tests.unit/test_bmp_object.py +++ b/tests.unit/test_bmp_object.py @@ -10,80 +10,89 @@ from edk2toollib.uefi.bmp_object import BmpObject import io -''' +""" # to import an image into hex use this import binascii filename = image_path with open(filename, 'rb') as f: content = f.read() print(binascii.hexlify(content)) -''' - -hamburger = bytes.fromhex(('424d3603000000000000360000002800000010000000100000' - '00010018000000000000000000c30e0000c30e00000000000000000000fffffff7f7f7669ccc43' - '87c3307abd186ab12474b92877ba2477be1e70bc2473b83c81be337cbd4789c3fffffffffffff6' - 'f6f6608fb92d70a11c666a0b57670d6e7f226fb54280b03a8f82228d661d886d0c6e990955a22e' - '78b986b1d8fffffff0f0f03b77ae257e57219b6920a87316a3661ba56a167c4e2b938d2cac8b19' - 'ac7920b18110799f004f9d2f79baffffffffffff146a60157e4c21907026928e289daf33b3d23d' - 'bee43fb8dd48b1d036a1a71e976824a47129997b11589cffffff78c0ec249bc9469bc5877cad5d' - '68854053721a335e182f571b2e592e4466515f799192ac9c82ad75c4c040a89edde6e826b0e54b' - 'b4db9394b0223554233a58364c6a334c6d3451762f4d75304e742b4569273d5a435271c3bcd661' - 'cbc15cbb9df1fafd7995a721395b173862113b692c4f7938557e3f5c7e4365893454812e4b7f32' - '4b7f34496f41506b9db2d0eaf6f5f5f5f54961791f42934a6fdc3e89c42aa1a6297e8e3a5cb534' - 'b79a279183324bdd2945d52a38b5333c8c516890abddf4f8f8f82649703e61ca41a5a053a1a25d' - '9db15c9cbd599ac3568fb5588ead5a93aa468e9133867a2c3eb7384089f7f7f7fdfdfd38889369' - 'a6b176a8cf5297d32b7fcd267bc92377c42e78b92777bf2975b93785cd4892d3589cba338281f7' - 'f7f7ffffff7ab8d2589cd62f79be367cbb3381c61870bb1169b61c71b80d68b73177b3286da92a' - '7cc5297ecc5197cbf4f6f7fcfdfd559ad53e89cf2e7fc32674b6a9c2db2272b61c6eb4b0cbe914' - '68b00b5b9e9db6d0377cb72b7cc4277ccbe8f1f8fdfdff2b81cb3e89ccb7d0ec1c6fb4206dac2e' - '6ea51b68a90f60a51b69aa0e63a91461a31764a52470b22579c2eff4fbffffffb2d0eb3f89ca36' - '81c13c82bd4086c091b0ce3a74a5115c990b599bafcae6055ba3085ba17fa5ca8bacbefbfbfbff' - 'fffff5f9fdaac7e05394cbb3cdea7faad06c9cc43f75a1a4b9cf125b98226ca7065ca40e65ae84' - 'a8becad3d5fbfbfbfffffffffffffafbfcc0d1e0619bcd4e8fc8468ac43d80bb3576aa256fad20' - '6cab1565a8aac8e2e7e9ebf8f8f8ffffff')) - -hamburger_lores = bytes.fromhex('424df60000000000000076000000280000001000000010' - '000000010004000000000080000000c30e0000c30e000000000000000000000000000000008000' - '008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ffff' - '00ff000000ff00ff00ffff0000ffffff00ff733333333333fff73333333333338ff33333323333' - '313ff32333bbbb33333f833733111138783fbb71111311113883f71111333311138ff319333333' - '999138f13333333333391ff377b3333333b33ff8b333333333333ffb3338338338333ff3383333' - '3333333ff83333833383377fff8388738333378ffff8733333338fff') - -bad_header_burger = bytes.fromhex('434df600000000000000760000002800000010000000' - '10000000010004000000000080000000c30e0000c30e0000000000000000000000000000000080' - '00008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ff' - 'ff00ff000000ff00ff00ffff0000ffffff00ff733333333333fff73333333333338ff333333233' - '33313ff32333bbbb33333f833733111138783fbb71111311113883f71111333311138ff3193333' - '33999138f13333333333391ff377b3333333b33ff8b333333333333ffb3338338338333ff33833' - '333333333ff83333833383377fff8388738333378ffff8733333338fff') - -bad_size_burger = bytes.fromhex('424df60000000000000076000000280000001000000010' - '000000010004000000000080000000c30e0000c30e0000' - '0000000000000000000000000000800000800000008080' - '0080000000800080008080000080808000c0c0c0000000' - 'ff0000ff000000ffff00ff000000ff00ff00ffff0000ff' - 'ffff00ff733333333333fff73333333333338ff3333332' - '3333313ff32333bbbb33333f833733111138783fbb7111' - '1311113883f71111333311138ff319333333999138f133' - '33333333391ff377b3333333b33ff8b333333333333ffb' - '3338338338333ff33833333333333ff83333833383377f' - 'ff8388738333378ffff873333333') +""" + +hamburger = bytes.fromhex( + ( + "424d3603000000000000360000002800000010000000100000" + "00010018000000000000000000c30e0000c30e00000000000000000000fffffff7f7f7669ccc43" + "87c3307abd186ab12474b92877ba2477be1e70bc2473b83c81be337cbd4789c3fffffffffffff6" + "f6f6608fb92d70a11c666a0b57670d6e7f226fb54280b03a8f82228d661d886d0c6e990955a22e" + "78b986b1d8fffffff0f0f03b77ae257e57219b6920a87316a3661ba56a167c4e2b938d2cac8b19" + "ac7920b18110799f004f9d2f79baffffffffffff146a60157e4c21907026928e289daf33b3d23d" + "bee43fb8dd48b1d036a1a71e976824a47129997b11589cffffff78c0ec249bc9469bc5877cad5d" + "68854053721a335e182f571b2e592e4466515f799192ac9c82ad75c4c040a89edde6e826b0e54b" + "b4db9394b0223554233a58364c6a334c6d3451762f4d75304e742b4569273d5a435271c3bcd661" + "cbc15cbb9df1fafd7995a721395b173862113b692c4f7938557e3f5c7e4365893454812e4b7f32" + "4b7f34496f41506b9db2d0eaf6f5f5f5f54961791f42934a6fdc3e89c42aa1a6297e8e3a5cb534" + "b79a279183324bdd2945d52a38b5333c8c516890abddf4f8f8f82649703e61ca41a5a053a1a25d" + "9db15c9cbd599ac3568fb5588ead5a93aa468e9133867a2c3eb7384089f7f7f7fdfdfd38889369" + "a6b176a8cf5297d32b7fcd267bc92377c42e78b92777bf2975b93785cd4892d3589cba338281f7" + "f7f7ffffff7ab8d2589cd62f79be367cbb3381c61870bb1169b61c71b80d68b73177b3286da92a" + "7cc5297ecc5197cbf4f6f7fcfdfd559ad53e89cf2e7fc32674b6a9c2db2272b61c6eb4b0cbe914" + "68b00b5b9e9db6d0377cb72b7cc4277ccbe8f1f8fdfdff2b81cb3e89ccb7d0ec1c6fb4206dac2e" + "6ea51b68a90f60a51b69aa0e63a91461a31764a52470b22579c2eff4fbffffffb2d0eb3f89ca36" + "81c13c82bd4086c091b0ce3a74a5115c990b599bafcae6055ba3085ba17fa5ca8bacbefbfbfbff" + "fffff5f9fdaac7e05394cbb3cdea7faad06c9cc43f75a1a4b9cf125b98226ca7065ca40e65ae84" + "a8becad3d5fbfbfbfffffffffffffafbfcc0d1e0619bcd4e8fc8468ac43d80bb3576aa256fad20" + "6cab1565a8aac8e2e7e9ebf8f8f8ffffff" + ) +) + +hamburger_lores = bytes.fromhex( + "424df60000000000000076000000280000001000000010" + "000000010004000000000080000000c30e0000c30e000000000000000000000000000000008000" + "008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ffff" + "00ff000000ff00ff00ffff0000ffffff00ff733333333333fff73333333333338ff33333323333" + "313ff32333bbbb33333f833733111138783fbb71111311113883f71111333311138ff319333333" + "999138f13333333333391ff377b3333333b33ff8b333333333333ffb3338338338333ff3383333" + "3333333ff83333833383377fff8388738333378ffff8733333338fff" +) + +bad_header_burger = bytes.fromhex( + "434df600000000000000760000002800000010000000" + "10000000010004000000000080000000c30e0000c30e0000000000000000000000000000000080" + "00008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ff" + "ff00ff000000ff00ff00ffff0000ffffff00ff733333333333fff73333333333338ff333333233" + "33313ff32333bbbb33333f833733111138783fbb71111311113883f71111333311138ff3193333" + "33999138f13333333333391ff377b3333333b33ff8b333333333333ffb3338338338333ff33833" + "333333333ff83333833383377fff8388738333378ffff8733333338fff" +) + +bad_size_burger = bytes.fromhex( + "424df60000000000000076000000280000001000000010" + "000000010004000000000080000000c30e0000c30e0000" + "0000000000000000000000000000800000800000008080" + "0080000000800080008080000080808000c0c0c0000000" + "ff0000ff000000ffff00ff000000ff00ff00ffff0000ff" + "ffff00ff733333333333fff73333333333338ff3333332" + "3333313ff32333bbbb33333f833733111138783fbb7111" + "1311113883f71111333311138ff319333333999138f133" + "33333333391ff377b3333333b33ff8b333333333333ffb" + "3338338338333ff33833333333333ff83333833383377f" + "ff8388738333378ffff873333333" +) class TestBmpObject(unittest.TestCase): - def test_good_header(self): file = io.BytesIO(hamburger) bmp = BmpObject(file) - self.assertEqual(bmp.CharB, b'B', "B header should be accurate") - self.assertEqual(bmp.CharM, b'M', "M header should be accurate") + self.assertEqual(bmp.CharB, b"B", "B header should be accurate") + self.assertEqual(bmp.CharM, b"M", "M header should be accurate") def test_lores_good_header(self): file = io.BytesIO(hamburger_lores) bmp = BmpObject(file) - self.assertEqual(bmp.CharB, b'B', "B header should be accurate") - self.assertEqual(bmp.CharM, b'M', "M header should be accurate") + self.assertEqual(bmp.CharB, b"B", "B header should be accurate") + self.assertEqual(bmp.CharM, b"M", "M header should be accurate") def test_get_width_height(self): file = io.BytesIO(hamburger) @@ -110,7 +119,7 @@ def test_get_24_bits(self): def test_bad_header(self): file = io.BytesIO(bad_header_burger) bmp = BmpObject(file) - self.assertNotEqual(bmp.CharB, b'B', "B header should be accurate") + self.assertNotEqual(bmp.CharB, b"B", "B header should be accurate") self.assertEqual(bmp.BitPerPixel, 4, "24 bits aren't accurate") def test_bad_image(self): diff --git a/tests.unit/test_cat_generator.py b/tests.unit/test_cat_generator.py index b95f9037..b43e2017 100644 --- a/tests.unit/test_cat_generator.py +++ b/tests.unit/test_cat_generator.py @@ -12,7 +12,6 @@ class CatGeneratorTest(unittest.TestCase): - def test_win10_OS(self): o = CatGenerator("x64", "win10") self.assertEqual(o.OperatingSystem, "10") diff --git a/tests.unit/test_dsc.py b/tests.unit/test_dsc.py index 04c8c231..08dd3958 100644 --- a/tests.unit/test_dsc.py +++ b/tests.unit/test_dsc.py @@ -16,7 +16,6 @@ class TestDscObject(unittest.TestCase): - def test_null_creation(self): d = dsc() self.assertNotEqual(d, None) @@ -51,7 +50,7 @@ def test_dsc_multple_library_classes(self): self.assertEqual(len(d.library_classes[IA32_section]), 2) def test_get_library_classes(self): - ''' This serves more as an example of how to walk the DSC to get a library class for a componenet ''' + """This serves more as an example of how to walk the DSC to get a library class for a componenet""" pass def test_put_in_bad_things(self): diff --git a/tests.unit/test_dsc_translator.py b/tests.unit/test_dsc_translator.py index 65a243d8..9d6987b5 100644 --- a/tests.unit/test_dsc_translator.py +++ b/tests.unit/test_dsc_translator.py @@ -9,6 +9,7 @@ import os import tempfile from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser + # from edk2toollib.uefi.edk2.build_objects.dsc import dsc from edk2toollib.uefi.edk2.build_objects.dsc_translator import DscTranslator diff --git a/tests.unit/test_firmware_policy.py b/tests.unit/test_firmware_policy.py index 59ad34b7..270e7471 100644 --- a/tests.unit/test_firmware_policy.py +++ b/tests.unit/test_firmware_policy.py @@ -12,7 +12,6 @@ class FirmwarePolicyTest(unittest.TestCase): - # A server-generated, non-firmware policy with 1 rule # Key: 81000000_Debug_DeviceID # ValueType: 5 @@ -24,7 +23,8 @@ class FirmwarePolicyTest(unittest.TestCase): 00 00 00 81 00 00 00 00 0C 00 00 00 1E 00 00 00 0A 00 44 00 65 00 62 00 75 00 67 00 10 00 44 00 65 00 76 00 69 00 63 00 65 00 49 00 44 00 05 00 - F6 AE 8C 94 3A 8C E2 C2""") + F6 AE 8C 94 3A 8C E2 C2""" + ) TEST_LEGACY_POLICY = bytearray.fromhex( """ @@ -254,7 +254,8 @@ class FirmwarePolicyTest(unittest.TestCase): 53 00 54 00 45 00 53 00 54 00 45 00 53 00 5C 00 31 00 33 00 35 00 02 00 04 80 00 00 04 00 00 00 00 00 05 00 00 00 00 00 01 00 00 00 08 00 00 00 - 0E 00 00 00 0F 00 00 00""") + 0E 00 00 00 0F 00 00 00""" + ) def test_basic_decode(self): inp = io.BytesIO(FirmwarePolicyTest.TEST_DEVICE_ID_C2E28) @@ -265,7 +266,7 @@ def test_basic_decode(self): self.assertEqual(policyManuf.Rules[0].SubKeyName.String, "Debug") self.assertEqual(policyManuf.Rules[0].ValueName.String, "DeviceID") self.assertEqual(policyManuf.Rules[0].Value.valueType.vt, 5) - self.assertEqual(policyManuf.Rules[0].Value.value, int(0xc2e28c3a948caef6)) + self.assertEqual(policyManuf.Rules[0].Value.value, int(0xC2E28C3A948CAEF6)) def test_basic_create_encode_decode_roundtrip(self): policyManuf = FirmwarePolicy() @@ -273,22 +274,23 @@ def test_basic_create_encode_decode_roundtrip(self): TargetInfo = { # EV Certificate Subject CN="", recommend matches SmbiosSystemManufacturer, # SMBIOS Table 1, offset 04h (System Manufacturer) - 'Manufacturer': 'Contoso Computers, LLC', + "Manufacturer": "Contoso Computers, LLC", # SmbiosSystemProductName, SMBIOS Table 1, offset 05h (System Product Name) - 'Product': 'Laptop Foo', + "Product": "Laptop Foo", # SmbiosSystemSerialNumber, SMBIOS System Information (Type 1 Table) -> Serial Number - 'SerialNumber': 'F0013-000243546-X02', + "SerialNumber": "F0013-000243546-X02", # Yours to define, or not use (NULL string), ODM name is suggested - 'OEM_01': 'ODM Foo', + "OEM_01": "ODM Foo", # Yours to define, or not use (NULL string) - 'OEM_02': '', + "OEM_02": "", # The following is randomly generated by the device - 'Nonce': nonce} + "Nonce": nonce, + } policyManuf.SetDeviceTarget(TargetInfo) - policy = \ - FirmwarePolicy.FW_POLICY_VALUE_ACTION_SECUREBOOT_CLEAR \ - | FirmwarePolicy.FW_POLICY_VALUE_ACTION_TPM_CLEAR + policy = ( + FirmwarePolicy.FW_POLICY_VALUE_ACTION_SECUREBOOT_CLEAR | FirmwarePolicy.FW_POLICY_VALUE_ACTION_TPM_CLEAR + ) policyManuf.SetDevicePolicy(policy) first_output = io.BytesIO() @@ -305,7 +307,7 @@ def test_basic_create_encode_decode_roundtrip(self): first_output.close() second_output.close() -# The below tests exercise larger error paths and code not normally travelled + # The below tests exercise larger error paths and code not normally travelled def test_legacy_decode(self): # This policy includes rules where SubKeyOffsets and ValueNameOffsets are reused @@ -317,7 +319,7 @@ def test_legacy_decode(self): self.assertEqual(legacyPolicy.Reserved2Count, 17) def test_decode_using_fs_parser(self): - """ By default the value table parser uses Byte[], but it supports BinaryIO filestreams when specified)""" + """By default the value table parser uses Byte[], but it supports BinaryIO filestreams when specified)""" inp = io.BytesIO(FirmwarePolicyTest.TEST_LEGACY_POLICY) policyManuf = FirmwarePolicy() policyManuf.FromFileStream(inp, False) diff --git a/tests.unit/test_fmp_capsule_header.py b/tests.unit/test_fmp_capsule_header.py index e58ea5c7..d169ef76 100644 --- a/tests.unit/test_fmp_capsule_header.py +++ b/tests.unit/test_fmp_capsule_header.py @@ -19,22 +19,22 @@ def test_should_successfully_decode_test_payload(self): def test_embedded_driver_count_should_track_additions(self): test_header = FmpCapsuleHeaderClass() self.assertEqual(test_header.EmbeddedDriverCount, 0) - test_header.AddEmbeddedDriver(b'dummydriver') + test_header.AddEmbeddedDriver(b"dummydriver") self.assertEqual(test_header.EmbeddedDriverCount, 1) - test_header.AddEmbeddedDriver(b'dummydriver2') + test_header.AddEmbeddedDriver(b"dummydriver2") self.assertEqual(test_header.EmbeddedDriverCount, 2) def test_payload_item_count_should_track_additions(self): test_header = FmpCapsuleHeaderClass() self.assertEqual(test_header.PayloadItemCount, 0) - test_header.AddFmpCapsuleImageHeader(b'dummyheader') + test_header.AddFmpCapsuleImageHeader(b"dummyheader") self.assertEqual(test_header.PayloadItemCount, 1) - test_header.AddFmpCapsuleImageHeader(b'dummyheader2') + test_header.AddFmpCapsuleImageHeader(b"dummyheader2") self.assertEqual(test_header.PayloadItemCount, 2) def test_encoding_twice_should_yield_identical_results(self): test_header = FmpCapsuleHeaderClass() - test_header.AddEmbeddedDriver(b'dummydriver') + test_header.AddEmbeddedDriver(b"dummydriver") encode_1 = test_header.Encode() encode_2 = test_header.Encode() self.assertEqual(encode_1, encode_2) diff --git a/tests.unit/test_guid_list.py b/tests.unit/test_guid_list.py index d6558e43..431623bf 100644 --- a/tests.unit/test_guid_list.py +++ b/tests.unit/test_guid_list.py @@ -16,7 +16,6 @@ class TestGuidListEntry(unittest.TestCase): - def test_valid_input(self): GUID = "66341ae8-668f-4192-b44d-5f87b868f041" NAME = "testguid" @@ -31,9 +30,7 @@ def test_valid_input(self): class TestGuidList(unittest.TestCase): - - SAMPLE_DEC_FILE = \ - """## @file + SAMPLE_DEC_FILE = """## @file TestDecFile ## @@ -69,8 +66,7 @@ class TestGuidList(unittest.TestCase): PcAtChipsetPkgExtra.uni """ - SAMPLE_INF_FILE = \ - """## @file + SAMPLE_INF_FILE = """## @file # Sample UEFI Application Reference EDKII Module. # # This is a sample shell application that will print "UEFI Hello World!" to the diff --git a/tests.unit/test_inf_generator.py b/tests.unit/test_inf_generator.py index 7b989b94..4cb9dd60 100644 --- a/tests.unit/test_inf_generator.py +++ b/tests.unit/test_inf_generator.py @@ -20,7 +20,7 @@ def _get_test_file(): class InfSectionTest(unittest.TestCase): def test_empty(self): - section = InfSection('TestSection') + section = InfSection("TestSection") self.assertEqual(str(section), "[TestSection]") def test_single(self): @@ -39,8 +39,15 @@ class InfGeneratorTest(unittest.TestCase): VALID_GUID_STRING = "3cad7a0c-d35b-4b75-96b1-03a9fb07b7fc" def test_valid(self): - o = InfGenerator("test_name", "provider", InfGeneratorTest.VALID_GUID_STRING, "x64", - "description", "aa.bb.cc.dd", "0xaabbccdd") + o = InfGenerator( + "test_name", + "provider", + InfGeneratorTest.VALID_GUID_STRING, + "x64", + "description", + "aa.bb.cc.dd", + "0xaabbccdd", + ) self.assertIsInstance(o, InfGenerator) self.assertEqual(o.Name, "test_name") self.assertEqual(o.Provider, "provider") @@ -64,8 +71,15 @@ def test_valid(self): def test_file(self): with tempfile.TemporaryDirectory() as tmpdir: inffile_path = os.path.join(tmpdir, "InfFile.inf") - infgen = InfGenerator('TestName', 'TestProvider', InfGeneratorTest.VALID_GUID_STRING, - "x64", "Test Description", "1.2.3.4", "0x01020304") + infgen = InfGenerator( + "TestName", + "TestProvider", + InfGeneratorTest.VALID_GUID_STRING, + "x64", + "Test Description", + "1.2.3.4", + "0x01020304", + ) infgen.MakeInf(inffile_path, "TestFirmwareRom.bin", False) with open(inffile_path, "r") as inffile: @@ -78,8 +92,15 @@ def test_file(self): def test_integrity_file_entry(self): with tempfile.TemporaryDirectory() as tmpdir: inffile_path = os.path.join(tmpdir, "InfFile.inf") - infgen = InfGenerator('TestName', 'TestProvider', InfGeneratorTest.VALID_GUID_STRING, - "x64", "Test Description", "1.2.3.4", "0x01020304") + infgen = InfGenerator( + "TestName", + "TestProvider", + InfGeneratorTest.VALID_GUID_STRING, + "x64", + "Test Description", + "1.2.3.4", + "0x01020304", + ) infgen.MakeInf(inffile_path, "TestFirmwareRom.bin", False) with open(inffile_path, "r") as inffile: file_contents = inffile.read() @@ -94,40 +115,75 @@ def test_integrity_file_entry(self): self.assertIn("FirmwareIntegrityFilename", file_contents) def test_invalid_name_symbol(self): - - InvalidChars = ['~', '`', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', ' ', '{', '[', '}', ']', '+', '='] + InvalidChars = ["~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", " ", "{", "[", "}", "]", "+", "="] for a in InvalidChars: with self.subTest(name="test{}name".format(a)): name = "test{}name".format(a) with self.assertRaises(ValueError): - InfGenerator(name, "provider", InfGeneratorTest.VALID_GUID_STRING, "x64", - "description", "aa.bb", "0xaabbccdd") + InfGenerator( + name, + "provider", + InfGeneratorTest.VALID_GUID_STRING, + "x64", + "description", + "aa.bb", + "0xaabbccdd", + ) def test_version_string_format(self): with self.subTest(version_string="zero ."): with self.assertRaises(ValueError): - InfGenerator("test_name", "provider", InfGeneratorTest.VALID_GUID_STRING, "x64", - "description", "1234", "0x100000000") + InfGenerator( + "test_name", + "provider", + InfGeneratorTest.VALID_GUID_STRING, + "x64", + "description", + "1234", + "0x100000000", + ) with self.subTest(version_string="> 3 ."): with self.assertRaises(ValueError): - InfGenerator("test_name", "provider", InfGeneratorTest.VALID_GUID_STRING, "x64", - "description", "1.2.3.4.5", "0x100000000") + InfGenerator( + "test_name", + "provider", + InfGeneratorTest.VALID_GUID_STRING, + "x64", + "description", + "1.2.3.4.5", + "0x100000000", + ) def test_version_hex_too_big(self): with self.subTest("hex string too big"): with self.assertRaises(ValueError): - InfGenerator("test_name", "provider", InfGeneratorTest.VALID_GUID_STRING, "x64", - "description", "aa.bb", "0x100000000") + InfGenerator( + "test_name", + "provider", + InfGeneratorTest.VALID_GUID_STRING, + "x64", + "description", + "aa.bb", + "0x100000000", + ) with self.subTest("decimal too big"): with self.assertRaises(ValueError): - InfGenerator("test_name", "provider", InfGeneratorTest.VALID_GUID_STRING, "x64", - "description", "aa.bb", "4294967296") + InfGenerator( + "test_name", + "provider", + InfGeneratorTest.VALID_GUID_STRING, + "x64", + "description", + "aa.bb", + "4294967296", + ) def test_version_hex_can_support_decimal(self): - o = InfGenerator("test_name", "provider", InfGeneratorTest.VALID_GUID_STRING, "x64", - "description", "aa.bb.cc.dd", "12356") + o = InfGenerator( + "test_name", "provider", InfGeneratorTest.VALID_GUID_STRING, "x64", "description", "aa.bb.cc.dd", "12356" + ) self.assertEqual(int(o.VersionHex, 0), 12356) def test_invalid_guid_format(self): @@ -137,7 +193,7 @@ def test_invalid_guid_format(self): # NOTE: Below are the expected contents of a a valid INF file. # Some fields will need to be generated (like the date). -TEST_FILE_CONTENTS = f'''; +TEST_FILE_CONTENTS = f"""; ; TestName.inf ; 1.2.3.4 ; Copyright (C) 2019 Microsoft Corporation. All Rights Reserved. @@ -193,4 +249,4 @@ def test_invalid_guid_format(self): ; non-localizable DIRID_WINDOWS = 10 REG_DWORD = 0x00010001 -''' +""" diff --git a/tests.unit/test_inf_generator2.py b/tests.unit/test_inf_generator2.py index 679b2dbd..8ebbcb8e 100644 --- a/tests.unit/test_inf_generator2.py +++ b/tests.unit/test_inf_generator2.py @@ -16,9 +16,10 @@ InfHeader, InfSourceFiles, InfStrings, - OS_BUILD_VERSION_DIRID13_SUPPORT + OS_BUILD_VERSION_DIRID13_SUPPORT, ) + class InfHeaderTest(unittest.TestCase): def test_header(self): Strings = InfStrings() @@ -45,9 +46,9 @@ def test_header(self): """) self.assertEqual(ExpectedStr, str(Header)) self.assertIn("Provider", Strings.LocalizableStrings) - self.assertEqual("testprovider", Strings.LocalizableStrings['Provider']) + self.assertEqual("testprovider", Strings.LocalizableStrings["Provider"]) self.assertIn("MfgName", Strings.LocalizableStrings) - self.assertEqual("testmfr", Strings.LocalizableStrings['MfgName']) + self.assertEqual("testmfr", Strings.LocalizableStrings["MfgName"]) def test_header_should_throw_for_bad_input(self): Strings = InfStrings() @@ -77,13 +78,8 @@ def test_firmware(self): SourceFiles = InfSourceFiles("diskname", Strings) Firmware = InfFirmware( - "tag", - "desc", - "34e094e9-4079-44cd-9450-3f2cb7824c97", - "0x01000001", - "test.bin", - Strings, - SourceFiles) + "tag", "desc", "34e094e9-4079-44cd-9450-3f2cb7824c97", "0x01000001", "test.bin", Strings, SourceFiles + ) ExpectedStr = textwrap.dedent("""\ [tag_Install.NT] @@ -108,7 +104,7 @@ def test_firmware(self): self.assertEqual(ExpectedStr, str(Firmware)) self.assertEqual(Firmware.Description, "desc") self.assertIn("REG_DWORD", Strings.NonLocalizableStrings) - self.assertEqual("0x00010001", Strings.NonLocalizableStrings['REG_DWORD']) + self.assertEqual("0x00010001", Strings.NonLocalizableStrings["REG_DWORD"]) self.assertIn("test.bin", SourceFiles.Files) def test_rollback_firmware(self): @@ -123,7 +119,8 @@ def test_rollback_firmware(self): "test.bin", Strings, SourceFiles, - Rollback=True) + Rollback=True, + ) ExpectedStr = textwrap.dedent("""\ [tag_Install.NT] @@ -152,7 +149,7 @@ def test_rollback_firmware(self): self.assertEqual(ExpectedStr, str(Firmware)) self.assertEqual(Firmware.Description, "desc") self.assertIn("REG_DWORD", Strings.NonLocalizableStrings) - self.assertEqual("0x00010001", Strings.NonLocalizableStrings['REG_DWORD']) + self.assertEqual("0x00010001", Strings.NonLocalizableStrings["REG_DWORD"]) self.assertIn("test.bin", SourceFiles.Files) def test_rollback_firmware_integrity(self): @@ -168,7 +165,8 @@ def test_rollback_firmware_integrity(self): Strings, SourceFiles, Rollback=True, - IntegrityFile="test2.bin") + IntegrityFile="test2.bin", + ) ExpectedStr = textwrap.dedent("""\ [tag_Install.NT] @@ -199,7 +197,7 @@ def test_rollback_firmware_integrity(self): self.assertEqual(ExpectedStr, str(Firmware)) self.assertEqual(Firmware.Description, "desc") self.assertIn("REG_DWORD", Strings.NonLocalizableStrings) - self.assertEqual("0x00010001", Strings.NonLocalizableStrings['REG_DWORD']) + self.assertEqual("0x00010001", Strings.NonLocalizableStrings["REG_DWORD"]) self.assertIn("test.bin", SourceFiles.Files) self.assertIn("test2.bin", SourceFiles.Files) @@ -217,7 +215,8 @@ def test_firmware_should_throw_for_bad_input(self): Strings, SourceFiles, Rollback=True, - IntegrityFile="test2.bin") + IntegrityFile="test2.bin", + ) with self.assertRaises(ValueError): InfFirmware( @@ -229,7 +228,8 @@ def test_firmware_should_throw_for_bad_input(self): Strings, SourceFiles, Rollback=True, - IntegrityFile="test2.bin") + IntegrityFile="test2.bin", + ) with self.assertRaises(ValueError): InfFirmware( @@ -241,7 +241,8 @@ def test_firmware_should_throw_for_bad_input(self): Strings, SourceFiles, Rollback=True, - IntegrityFile="test2.bin") + IntegrityFile="test2.bin", + ) with self.assertRaises(ValueError): InfFirmware( @@ -253,7 +254,8 @@ def test_firmware_should_throw_for_bad_input(self): Strings, SourceFiles, Rollback=True, - IntegrityFile="test2.bin") + IntegrityFile="test2.bin", + ) class InfFirmwareSectionsTest(unittest.TestCase): @@ -262,15 +264,10 @@ def test_one_section(self): SourceFiles = InfSourceFiles("diskname", Strings) Firmware = InfFirmware( - "tag", - "desc", - "34e094e9-4079-44cd-9450-3f2cb7824c97", - "0x01000001", - "test.bin", - Strings, - SourceFiles) + "tag", "desc", "34e094e9-4079-44cd-9450-3f2cb7824c97", "0x01000001", "test.bin", Strings, SourceFiles + ) - Sections = InfFirmwareSections('amd64', Strings) + Sections = InfFirmwareSections("amd64", Strings) Sections.AddSection(Firmware) ExpectedStr = textwrap.dedent(f"""\ @@ -298,11 +295,11 @@ def test_one_section(self): self.assertEqual(ExpectedStr, str(Sections)) self.assertIn("tagDesc", Strings.LocalizableStrings) - self.assertEqual("desc", Strings.LocalizableStrings['tagDesc']) + self.assertEqual("desc", Strings.LocalizableStrings["tagDesc"]) self.assertIn("test.bin", SourceFiles.Files) self.assertIn("REG_DWORD", Strings.NonLocalizableStrings) - self.assertEqual("0x00010001", Strings.NonLocalizableStrings['REG_DWORD']) + self.assertEqual("0x00010001", Strings.NonLocalizableStrings["REG_DWORD"]) def test_two_sections(self): self.maxDiff = None @@ -310,24 +307,14 @@ def test_two_sections(self): SourceFiles = InfSourceFiles("diskname", Strings) Firmware1 = InfFirmware( - "tag1", - "desc1", - "34e094e9-4079-44cd-9450-3f2cb7824c97", - "0x01000001", - "test1.bin", - Strings, - SourceFiles) + "tag1", "desc1", "34e094e9-4079-44cd-9450-3f2cb7824c97", "0x01000001", "test1.bin", Strings, SourceFiles + ) Firmware2 = InfFirmware( - "tag2", - "desc2", - "bec9124f-9934-4ec0-a6ed-b8bc1c91d276", - "0x01000002", - "test2.bin", - Strings, - SourceFiles) + "tag2", "desc2", "bec9124f-9934-4ec0-a6ed-b8bc1c91d276", "0x01000002", "test2.bin", Strings, SourceFiles + ) - Sections = InfFirmwareSections('amd64', Strings) + Sections = InfFirmwareSections("amd64", Strings) Sections.AddSection(Firmware1) Sections.AddSection(Firmware2) @@ -374,20 +361,20 @@ def test_two_sections(self): self.assertEqual(ExpectedStr, str(Sections)) self.assertIn("tag1Desc", Strings.LocalizableStrings) - self.assertEqual("desc1", Strings.LocalizableStrings['tag1Desc']) + self.assertEqual("desc1", Strings.LocalizableStrings["tag1Desc"]) self.assertIn("test1.bin", SourceFiles.Files) self.assertIn("tag2Desc", Strings.LocalizableStrings) - self.assertEqual("desc2", Strings.LocalizableStrings['tag2Desc']) + self.assertEqual("desc2", Strings.LocalizableStrings["tag2Desc"]) self.assertIn("test2.bin", SourceFiles.Files) self.assertIn("REG_DWORD", Strings.NonLocalizableStrings) - self.assertEqual("0x00010001", Strings.NonLocalizableStrings['REG_DWORD']) + self.assertEqual("0x00010001", Strings.NonLocalizableStrings["REG_DWORD"]) def test_firmware_sections_should_throw_for_bad_input(self): Strings = InfStrings() with self.assertRaises(ValueError): - InfFirmwareSections('foobar', Strings) + InfFirmwareSections("foobar", Strings) class InfSourceFilesTest(unittest.TestCase): @@ -414,9 +401,9 @@ def test_source_files(self): self.assertEqual(ExpectedStr, str(SourceFiles)) self.assertIn("DiskName", Strings.LocalizableStrings) - self.assertEqual("diskname", Strings.LocalizableStrings['DiskName']) + self.assertEqual("diskname", Strings.LocalizableStrings["DiskName"]) self.assertIn("DIRID_WINDOWS", Strings.NonLocalizableStrings) - self.assertEqual("10", Strings.NonLocalizableStrings['DIRID_WINDOWS']) + self.assertEqual("10", Strings.NonLocalizableStrings["DIRID_WINDOWS"]) def test_source_files_should_throw_on_bad_input(self): Strings = InfStrings() @@ -476,19 +463,9 @@ class InfFileTest(unittest.TestCase): def test_inf_file(self): File = InfFile("CapsuleName", "1.0.0.1", "01/01/2021", "Test Provider", "Test Manufacturer") - File.AddFirmware( - "tag1", - "desc1", - "34e094e9-4079-44cd-9450-3f2cb7824c97", - "0x01000001", - "test1.bin") + File.AddFirmware("tag1", "desc1", "34e094e9-4079-44cd-9450-3f2cb7824c97", "0x01000001", "test1.bin") - File.AddFirmware( - "tag2", - "desc2", - "bec9124f-9934-4ec0-a6ed-b8bc1c91d276", - "0x01000002", - "test2.bin") + File.AddFirmware("tag2", "desc2", "bec9124f-9934-4ec0-a6ed-b8bc1c91d276", "0x01000002", "test2.bin") ExpectedStr = textwrap.dedent(f"""\ ; @@ -575,20 +552,12 @@ def test_inf_file_rollback(self): File = InfFile("CapsuleName", "1.0.0.1", "01/01/2021", "Test Provider", "Test Manufacturer") File.AddFirmware( - "tag1", - "desc1", - "34e094e9-4079-44cd-9450-3f2cb7824c97", - "0x01000001", - "test1.bin", - Rollback=True) + "tag1", "desc1", "34e094e9-4079-44cd-9450-3f2cb7824c97", "0x01000001", "test1.bin", Rollback=True + ) File.AddFirmware( - "tag2", - "desc2", - "bec9124f-9934-4ec0-a6ed-b8bc1c91d276", - "0x01000002", - "test2.bin", - Rollback=True) + "tag2", "desc2", "bec9124f-9934-4ec0-a6ed-b8bc1c91d276", "0x01000002", "test2.bin", Rollback=True + ) ExpectedStr = textwrap.dedent(f"""\ ; @@ -689,7 +658,8 @@ def test_inf_file_rollback_integrity(self): "0x01000001", "test1.bin", Rollback=True, - IntegrityFile="integrity1.bin") + IntegrityFile="integrity1.bin", + ) File.AddFirmware( "tag2", @@ -698,7 +668,8 @@ def test_inf_file_rollback_integrity(self): "0x01000002", "test2.bin", Rollback=True, - IntegrityFile="integrity2.bin") + IntegrityFile="integrity2.bin", + ) ExpectedStr = textwrap.dedent(f"""\ ; diff --git a/tests.unit/test_junit_report_format.py b/tests.unit/test_junit_report_format.py index bb6c25d9..cea104d0 100644 --- a/tests.unit/test_junit_report_format.py +++ b/tests.unit/test_junit_report_format.py @@ -16,7 +16,6 @@ class TestJunitTestReport(unittest.TestCase): - def __init__(self, *args, **kwargs): self.test_dir = None super().__init__(*args, **kwargs) @@ -84,7 +83,7 @@ def test_incomplete_test_results(self): def test_xml_escape_in_testcase_name_classname_output(self): jr = junit_report_format.JunitTestReport() jts = jr.create_new_testsuite("testname", "testpackage") - jtc = jts.create_new_testcase("test_failed\"<", ">&'testcase.test.failed") + jtc = jts.create_new_testcase('test_failed"<', ">&'testcase.test.failed") jtc.SetSuccess() f = os.path.join(self.test_dir, "testoutput.xml") jr.Output(f) @@ -94,7 +93,7 @@ def test_xml_escape_in_testcase_name_classname_output(self): def test_xml_escape_in_testsuit_name_package_output(self): jr = junit_report_format.JunitTestReport() - jts = jr.create_new_testsuite("testname\"<", ">&'testpackage") + jts = jr.create_new_testsuite('testname"<', ">&'testpackage") jtc = jts.create_new_testcase("test_failed", "testcase.test.failed") jtc.SetSuccess() f = os.path.join(self.test_dir, "testoutput.xml") @@ -153,7 +152,7 @@ def test_xml_escape_in_error_msg(self): jr = junit_report_format.JunitTestReport() jts = jr.create_new_testsuite("testname", "testpackage") jtc = jts.create_new_testcase("test_error", "testcase.test.error") - jtc.SetError("Message in Error\" case with < & char", "Error") + jtc.SetError('Message in Error" case with < & char', "Error") f = os.path.join(self.test_dir, "testoutput.xml") jr.Output(f) self.assertTrue(os.path.isfile(f)) @@ -164,7 +163,7 @@ def test_xml_escape_in_error_type(self): jr = junit_report_format.JunitTestReport() jts = jr.create_new_testsuite("testname", "testpackage") jtc = jts.create_new_testcase("test_error", "testcase.test.error") - jtc.SetError("Message in Error case", 'Error&') + jtc.SetError("Message in Error case", "Error&") f = os.path.join(self.test_dir, "testoutput.xml") jr.Output(f) self.assertTrue(os.path.isfile(f)) diff --git a/tests.unit/test_locate_tools.py b/tests.unit/test_locate_tools.py index 76f85c4f..b68bfc86 100644 --- a/tests.unit/test_locate_tools.py +++ b/tests.unit/test_locate_tools.py @@ -16,7 +16,6 @@ class LocateToolsTest(unittest.TestCase): - @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") def test_GetVsWherePath(self): # Gets VSWhere @@ -102,10 +101,11 @@ def test_FindToolInWinSdkWithNoValidProduct(self): results = locate_tools.FindToolInWinSdk("WontFind.exe", product="YouWontFindThis") self.assertIsNone(results) -@pytest.mark.skipif(not sys.platform.startswith("win"), reason = "requires Windows") + +@pytest.mark.skipif(not sys.platform.startswith("win"), reason="requires Windows") def test_QueryVcVariablesWithLargePathEnv(caplog): """Tests QueryVcVariables with a PATH Env over 8191 characters. - + When calling a .bat file, the environment is passed in, however any environment variable greater than 8191 is quietly ignored. This can sometimes happen with the PATH variable, but we almost always need the PATH env variable when querying VcVariables, so we want to warn when the user @@ -118,17 +118,17 @@ def test_QueryVcVariablesWithLargePathEnv(caplog): old_env = os.environ - os.environ["PATH"] += "TEST;" * 1640 # Makes path over 8191 characters + os.environ["PATH"] += "TEST;" * 1640 # Makes path over 8191 characters locate_tools.QueryVcVariables(keys) assert (len(caplog.records)) == 1 os.environ = old_env -@pytest.mark.skipif(not sys.platform.startswith("win"), reason = "requires Windows") +@pytest.mark.skipif(not sys.platform.startswith("win"), reason="requires Windows") def test_QueryVcVariablesWithLargEnv(caplog): """Tests QueryVcVariables when the entire Env is over 8191 character. - + calling a command on the cmd is limited to 8191 characters. The enviornment is counted in this limit. When the character limit is reached, the command simply errors out. Windows tries to fix this by not including any environment over 8191 characters (as seen in the test above), but when no individual environment variable is over @@ -137,7 +137,7 @@ def test_QueryVcVariablesWithLargEnv(caplog): keys = ["WindowsSdkDir", "WindowsSDKVersion"] old_env = os.environ - os.environ["PATH"] = "TEST;" * 1630 # Get close, but don't go over 8191 characters + os.environ["PATH"] = "TEST;" * 1630 # Get close, but don't go over 8191 characters with pytest.raises(RuntimeError): locate_tools.QueryVcVariables(keys) diff --git a/tests.unit/test_path_utilities.py b/tests.unit/test_path_utilities.py index 6fec7a73..0cc28350 100644 --- a/tests.unit/test_path_utilities.py +++ b/tests.unit/test_path_utilities.py @@ -19,16 +19,15 @@ class PathUtilitiesTest(unittest.TestCase): - def _make_file_helper(self, parentpath: str, filename: str) -> None: - '''Simple internal helper to make a file and write basic content.''' + """Simple internal helper to make a file and write basic content.""" with open(os.path.join(parentpath, filename), "w") as f: f.write("Unit test content") def _make_edk2_module_helper(self, parentpath: str, modname: str, extension_case_lower: bool = True) -> str: - '''Simple internal helper to make a folder and inf like edk2 + """Simple internal helper to make a folder and inf like edk2 return the path to the module folder. - ''' + """ modfolder = os.path.join(parentpath, modname) os.makedirs(modfolder, exist_ok=True) fn = modname + (".inf" if extension_case_lower else ".INF") @@ -36,7 +35,7 @@ def _make_edk2_module_helper(self, parentpath: str, modname: str, extension_case return modfolder def _make_edk2_package_helper(self, path: str, packagename: str, extension_case_lower: bool = True) -> str: - '''Simple internal helper to make an ed2 package as follows: + """Simple internal helper to make an ed2 package as follows: path/ packagename/ @@ -49,7 +48,7 @@ def _make_edk2_package_helper(self, path: str, packagename: str, extension_case_ TestFile.c return the path to the new package - ''' + """ pkgfolder = os.path.join(path, packagename) os.makedirs(pkgfolder, exist_ok=True) pn = packagename + (".dec" if extension_case_lower else ".DEC") @@ -62,17 +61,17 @@ def _make_edk2_package_helper(self, path: str, packagename: str, extension_case_ return pkgfolder def setUp(self): - '''Unittest fixture run before each test. + """Unittest fixture run before each test. Create a tmpdir and set the current working dir there. - ''' + """ self.tmp = tempfile.mkdtemp() self.precwd = os.getcwd() os.chdir(self.tmp) # move to tempfile root def tearDown(self): - '''Unittest fixture run after each test. + """Unittest fixture run after each test. Delete the tempdir and set the current working dir back. - ''' + """ os.chdir(self.precwd) if os.path.isdir(self.tmp): shutil.rmtree(self.tmp) @@ -80,12 +79,12 @@ def tearDown(self): # TESTS def test_basic_init_ws_abs(self): - '''Test edk2path with valid absolute path to workspace.''' + """Test edk2path with valid absolute path to workspace.""" pathobj = Edk2Path(self.tmp, []) self.assertEqual(pathobj.WorkspacePath, self.tmp) def test_basic_init_ws_cwd(self): - '''Test edk2path with a relative path to workspace.''' + """Test edk2path with a relative path to workspace.""" relpath = "testrootfolder" fullpath = os.path.join(self.tmp, relpath) os.mkdir(fullpath) @@ -93,13 +92,13 @@ def test_basic_init_ws_cwd(self): self.assertEqual(pathobj.WorkspacePath, fullpath) def test_nonexistant_ws(self): - '''Test edk2path with invalid workspace.''' + """Test edk2path with invalid workspace.""" invalid_ws = os.path.join(self.tmp, "invalidpath") with self.assertRaises(Exception): Edk2Path(invalid_ws, []) def test_nonexistant_abs(self): - '''Test edk2path with valid ws but invalid pp.''' + """Test edk2path with valid ws but invalid pp.""" pp = "doesnot_exist" pp_full_1 = os.path.join(self.tmp, pp) # absolute path @@ -113,13 +112,13 @@ def test_nonexistant_abs(self): self.assertEqual(len(pathobj.PackagePathList), 0) def test_pp_inside_workspace(self): - '''Test with packagespath pointing to folder nested inside workspace + """Test with packagespath pointing to folder nested inside workspace root/ <-- current working directory folder_ws/ <-- workspace root folder_pp/ <-- packages path pp packages here ws packages here. - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -143,14 +142,14 @@ def test_pp_inside_workspace(self): self.assertEqual(pathobj.PackagePathList[0], folder_pp1_abs) def test_pp_outside_workspace(self): - '''Test with packagespath pointing to folder outside of workspace + """Test with packagespath pointing to folder outside of workspace root/ <-- current working directory folder_ws/ <-- workspace root ws packages here folder_pp/ <-- packages path pp packages here. - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -176,9 +175,9 @@ def test_invalid_pp(self): with self.assertRaises(NotADirectoryError) as context: Edk2Path(str(ws), ["bad_pp_path", "bad_pp_path2", "good_path"], error_on_invalid_pp=True) - self.assertTrue('bad_pp_path' in str(context.exception)) - self.assertTrue('bad_pp_path2' in str(context.exception)) - self.assertTrue('good_path' not in str(context.exception)) + self.assertTrue("bad_pp_path" in str(context.exception)) + self.assertTrue("bad_pp_path2" in str(context.exception)) + self.assertTrue("good_path" not in str(context.exception)) # Make sure we don't throw an exception unless we mean to Edk2Path(str(ws), ["bad_pp_path", "bad_pp_path2", "good_path"], error_on_invalid_pp=False) @@ -193,7 +192,7 @@ def test_basic_init_ws_abs_different_case(self): self.assertNotEqual(pathobj.WorkspacePath, self.tmp) def test_get_containing_package_inside_workspace(self): - '''Test basic usage of GetContainingPackage with packages path nested + """Test basic usage of GetContainingPackage with packages path nested inside the workspace. File layout: @@ -217,7 +216,7 @@ def test_get_containing_package_inside_workspace(self): module2.inf X64/ TestFile.c - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -266,7 +265,7 @@ def test_get_containing_package_inside_workspace(self): self.assertIsNone(pathobj.GetContainingPackage(p)) def test_get_containing_package_outside_workspace(self): - '''Test basic usage of GetContainingPackage with packages path + """Test basic usage of GetContainingPackage with packages path outside the workspace. File layout: @@ -290,7 +289,7 @@ def test_get_containing_package_outside_workspace(self): module2.INF X64/ TestFile.c - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -333,7 +332,7 @@ def test_get_containing_package_outside_workspace(self): @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") def test_get_containing_package_ws_abs_different_case(self): - '''Test basic usage of GetContainingPackage when the workspace path has different case for + """Test basic usage of GetContainingPackage when the workspace path has different case for the drive letter then the incoming paths. This can happen on Windows if os.path.realpath is used. @@ -358,7 +357,7 @@ def test_get_containing_package_ws_abs_different_case(self): module2.inf X64/ TestFile.c - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) wsi_abs = os.path.join(self.tmp, ws_rel.capitalize()) # invert the case of the first char of the ws folder name @@ -405,7 +404,7 @@ def test_get_containing_package_ws_abs_different_case(self): self.assertIsNone(pathobj.GetContainingPackage(p), folder_pp_rel) def test_get_containing_package_with_nonexistent_path(self): - '''Test basic usage of GetContainingPackage when the file path does not exist. + """Test basic usage of GetContainingPackage when the file path does not exist. File layout: @@ -428,7 +427,7 @@ def test_get_containing_package_with_nonexistent_path(self): module2.inf X64/ TestFile.c - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) wsi_abs = os.path.join(self.tmp, ws_rel) @@ -513,7 +512,7 @@ def test_get_containing_modules_with_relative_path(self): self.assertRaises(Exception, pathobj.GetContainingModules, p) def test_get_containing_module_with_infs_in_other_temp_dirs(self): - '''Test that GetContainingModule does not look outside the workspace + """Test that GetContainingModule does not look outside the workspace root for modules. To do so, a temporary .inf file is placed in the user's temporary directory. Such a file could already exist and similarly impact test results. To ensure consistent test results, this @@ -533,7 +532,7 @@ def test_get_containing_module_with_infs_in_other_temp_dirs(self): module2.inf X64 TestFile.c - ''' + """ # Make the workspace directory: /folder_ws/ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) @@ -545,7 +544,7 @@ def test_get_containing_module_with_infs_in_other_temp_dirs(self): # Place a .inf file in the temporary directory # /SomeModule.inf other_inf = os.path.join(os.path.dirname(self.tmp), "SomeModule.inf") - with open(other_inf, 'w'): + with open(other_inf, "w"): pass try: @@ -624,7 +623,7 @@ def test_get_containing_modules_path_format(self): self.assertEqual(expected_module_inf, actual_module_inf_list[0]) def test_get_containing_module(self): - '''Test basic usage of GetContainingModule with packages path nested + """Test basic usage of GetContainingModule with packages path nested inside the workspace. File layout: @@ -648,7 +647,7 @@ def test_get_containing_module(self): module2.inf X64/ TestFile.c - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -670,9 +669,7 @@ def test_get_containing_module(self): p = os.path.join(ws_pkg_abs, "module1", "testfile.c") relist = pathobj.GetContainingModules(p) self.assertEqual(len(relist), 1) - self.assertEqual( - Path(os.path.join(ws_pkg_abs, "module1", "module1.inf")), - Path(relist[0])) + self.assertEqual(Path(os.path.join(ws_pkg_abs, "module1", "module1.inf")), Path(relist[0])) # file in workspace root - no package- should return ws root p = os.path.join(ws_abs, "testfile.c") @@ -688,17 +685,13 @@ def test_get_containing_module(self): p = os.path.join(ws_pkg_abs, "module2", "X64", "testfile.c") relist = pathobj.GetContainingModules(p) self.assertEqual(len(relist), 1) - self.assertEqual( - Path(os.path.join(ws_pkg_abs, "module2", "module2.inf")), - Path(relist[0])) + self.assertEqual(Path(os.path.join(ws_pkg_abs, "module2", "module2.inf")), Path(relist[0])) # inf file in module2 x64 p = os.path.join(ws_pkg_abs, "module2", "module2.inf") relist = pathobj.GetContainingModules(p) self.assertEqual(len(relist), 1) - self.assertEqual( - Path(os.path.join(ws_pkg_abs, "module2", "module2.inf")), - Path(relist[0])) + self.assertEqual(Path(os.path.join(ws_pkg_abs, "module2", "module2.inf")), Path(relist[0])) # file in PPTestPkg root p = os.path.join(pp_pkg_abs, "testfile.c") @@ -709,17 +702,13 @@ def test_get_containing_module(self): p = os.path.join(pp_pkg_abs, "module1", "testfile.c") relist = pathobj.GetContainingModules(p) self.assertEqual(len(relist), 1) - self.assertEqual( - Path(os.path.join(pp_pkg_abs, "module1", "module1.INF")), - Path(relist[0])) + self.assertEqual(Path(os.path.join(pp_pkg_abs, "module1", "module1.INF")), Path(relist[0])) # inf file in module in PPTestPkg p = os.path.join(pp_pkg_abs, "module1", "module1.INF") relist = pathobj.GetContainingModules(p) self.assertEqual(len(relist), 1) - self.assertEqual( - Path(os.path.join(pp_pkg_abs, "module1", "module1.INF")), - Path(relist[0])) + self.assertEqual(Path(os.path.join(pp_pkg_abs, "module1", "module1.INF")), Path(relist[0])) # file in packages path root - no module p = os.path.join(folder_pp1_abs, "testfile.c") @@ -741,9 +730,7 @@ def test_get_containing_module(self): p = os.path.join(ws_pkg_abs, "module1", "ThisParentDirDoesNotExist", "testfile.c") relist = pathobj.GetContainingModules(p) self.assertEqual(len(relist), 1) - self.assertEqual( - Path(os.path.join(ws_pkg_abs, "module1", "module1.inf")), - Path(relist[0])) + self.assertEqual(Path(os.path.join(ws_pkg_abs, "module1", "module1.inf")), Path(relist[0])) def test_get_edk2_relative_path_from_absolute_path_posix(self): """Test that relative path returned is a POSIX path. @@ -806,11 +793,13 @@ def test_get_edk2_relative_path_from_absolute_path_posix(self): actual_rel_from_abs_path = pathobj.GetEdk2RelativePathFromAbsolutePath(p) self.assertEqual(expected_rel_from_abs_path, actual_rel_from_abs_path) - actual_rel_from_abs_path = pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module_2", "X64", "TestFile.inf") + actual_rel_from_abs_path = pathobj.GetEdk2RelativePathFromAbsolutePath( + ws_pkg_abs, "module_2", "X64", "TestFile.inf" + ) self.assertEqual(expected_rel_from_abs_path, actual_rel_from_abs_path) def test_get_edk2_relative_path_from_absolute_path(self): - '''Test basic usage of GetEdk2RelativePathFromAbsolutePath with packages path nested + """Test basic usage of GetEdk2RelativePathFromAbsolutePath with packages path nested inside the workspace. File layout: @@ -834,7 +823,7 @@ def test_get_edk2_relative_path_from_absolute_path(self): module2.inf X64/ TestFile.c - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -854,17 +843,24 @@ def test_get_edk2_relative_path_from_absolute_path(self): # file in workspace p = os.path.join(ws_pkg_abs, "module2", "X64", "TestFile.c") self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/module2/X64/TestFile.c") - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module2", "X64", "TestFile.c"), f"{ws_p_name}/module2/X64/TestFile.c") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module2", "X64", "TestFile.c"), + f"{ws_p_name}/module2/X64/TestFile.c", + ) # Folder in packages path p = os.path.join(pp_pkg_abs, "module2", "X64") self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{pp_p_name}/module2/X64") - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp_pkg_abs, "module2", "X64"), f"{pp_p_name}/module2/X64") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(pp_pkg_abs, "module2", "X64"), f"{pp_p_name}/module2/X64" + ) # Folder in workspace p = os.path.join(ws_pkg_abs, "module2", "X64") self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/module2/X64") - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module2", "X64"), f"{ws_p_name}/module2/X64") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module2", "X64"), f"{ws_p_name}/module2/X64" + ) # file not in workspace p = os.path.join(self.tmp, "module2", "X64", "TestFile.c") @@ -882,15 +878,20 @@ def test_get_edk2_relative_path_from_absolute_path(self): # file is cwd relative but not absolute path p = os.path.join(ws_rel, ws_p_name, "module2", "X64", "TestFile.c") self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(p)) - self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_rel, ws_p_name, "module2", "X64", "TestFile.c")) + self.assertIsNone( + pathobj.GetEdk2RelativePathFromAbsolutePath(ws_rel, ws_p_name, "module2", "X64", "TestFile.c") + ) # ensure converted path keeps original capitalization p = os.path.join(ws_pkg_abs, "Module2", "x64", "TESTFILE.C") self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/Module2/x64/TESTFILE.C") - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "Module2", "x64", "TESTFILE.C"), f"{ws_p_name}/Module2/x64/TESTFILE.C") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "Module2", "x64", "TESTFILE.C"), + f"{ws_p_name}/Module2/x64/TESTFILE.C", + ) def test_get_relative_path_when_packages_path_list_contains_substrings(self): - '''Test usage of GetEdk2RelativePathFromAbsolutePath when members of PackagePathList contain + """Test usage of GetEdk2RelativePathFromAbsolutePath when members of PackagePathList contain substrings of themselves, for example "MU" and "MU_TIANO" File layout: root/ <-- current working directory (self.tmp) @@ -909,7 +910,7 @@ def test_get_relative_path_when_packages_path_list_contains_substrings(self): module2.INF X64/ TestFile2.c. - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -926,10 +927,13 @@ def test_get_relative_path_when_packages_path_list_contains_substrings(self): # file in workspace p = os.path.join(ws_pkg_abs, "module2", "X64", "TestFile2.c") self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{ws_p_name}/module2/X64/TestFile2.c") - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module2", "X64", "TestFile2.c"), f"{ws_p_name}/module2/X64/TestFile2.c") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(ws_pkg_abs, "module2", "X64", "TestFile2.c"), + f"{ws_p_name}/module2/X64/TestFile2.c", + ) def test_get_relative_path_when_package_path_inside_package(self): - '''Test a package_path directory inside the subfolders of a package. + """Test a package_path directory inside the subfolders of a package. Should not raise an exception. File layout: @@ -945,7 +949,7 @@ def test_get_relative_path_when_package_path_inside_package(self): module2.inf X64/ TestFile.c - ''' + """ folder_ws_rel = "folder_ws" folder_ws_abs = os.path.join(self.tmp, folder_ws_rel) os.mkdir(folder_ws_abs) @@ -964,10 +968,13 @@ def test_get_relative_path_when_package_path_inside_package(self): pathobj = Edk2Path(folder_ws_abs, [folder_pp1_abs, folder_pp2_abs]) p = os.path.join(pp1_abs, "module2", "X64", "TestFile.c") self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{pp1_name}/module2/X64/TestFile.c") - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp1_abs, "module2", "X64", "TestFile.c"), f"{pp1_name}/module2/X64/TestFile.c") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(pp1_abs, "module2", "X64", "TestFile.c"), + f"{pp1_name}/module2/X64/TestFile.c", + ) def test_get_relative_path_with_nested_packages(self): - '''Test a two package paths that contain nested packages. + """Test a two package paths that contain nested packages. Should raise an exception due to nested packages. File layout: @@ -991,7 +998,7 @@ def test_get_relative_path_with_nested_packages(self): module2.inf X64/ TestFile.c - ''' + """ folder_ws_rel = "folder_ws" folder_ws_abs = os.path.join(self.tmp, folder_ws_rel) os.mkdir(folder_ws_abs) @@ -1016,9 +1023,8 @@ def test_get_relative_path_with_nested_packages(self): Edk2Path(folder_ws_abs, [folder_pp1_abs, folder_pp2_abs]) self.assertEqual(len(logs.records), 2) - def test_get_relative_path_when_folder_is_next_to_package(self): - '''Test usage of GetEdk2RelativePathFromAbsolutePath when a folder containing a package is in the same + """Test usage of GetEdk2RelativePathFromAbsolutePath when a folder containing a package is in the same directory as a different package. This test ensures the correct value is returned regardless the order of the package paths. file layout: @@ -1028,7 +1034,7 @@ def test_get_relative_path_when_folder_is_next_to_package(self): PPTestPkg1 <-- A Package folder_pp2/ <-- A Package Path PPTestPkg2 <-- A Package. - ''' + """ folder_ws_rel = "folder_ws" folder_ws_abs = os.path.join(self.tmp, folder_ws_rel) os.mkdir(folder_ws_abs) @@ -1050,23 +1056,31 @@ def test_get_relative_path_when_folder_is_next_to_package(self): p2 = os.path.join(pp2_abs, "module2", "X64", "TestFile2.c") pathobj = Edk2Path(folder_ws_abs, [folder_pp1_abs, folder_pp2_abs]) - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p1), f'{pp1_name}/module2/X64/TestFile2.c') - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p2), f'{pp2_name}/module2/X64/TestFile2.c') - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp1_abs, "module2", "X64", "TestFile2.c"), - f'{pp1_name}/module2/X64/TestFile2.c') - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp2_abs, "module2", "X64", "TestFile2.c"), - f'{pp2_name}/module2/X64/TestFile2.c') + self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p1), f"{pp1_name}/module2/X64/TestFile2.c") + self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p2), f"{pp2_name}/module2/X64/TestFile2.c") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(pp1_abs, "module2", "X64", "TestFile2.c"), + f"{pp1_name}/module2/X64/TestFile2.c", + ) + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(pp2_abs, "module2", "X64", "TestFile2.c"), + f"{pp2_name}/module2/X64/TestFile2.c", + ) pathobj = Edk2Path(folder_ws_abs, [folder_pp2_abs, folder_pp1_abs]) - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p1), f'{pp1_name}/module2/X64/TestFile2.c') - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p2), f'{pp2_name}/module2/X64/TestFile2.c') - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp1_abs, "module2", "X64", "TestFile2.c"), - f'{pp1_name}/module2/X64/TestFile2.c') - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(pp2_abs, "module2", "X64", "TestFile2.c"), - f'{pp2_name}/module2/X64/TestFile2.c') + self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p1), f"{pp1_name}/module2/X64/TestFile2.c") + self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p2), f"{pp2_name}/module2/X64/TestFile2.c") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(pp1_abs, "module2", "X64", "TestFile2.c"), + f"{pp1_name}/module2/X64/TestFile2.c", + ) + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(pp2_abs, "module2", "X64", "TestFile2.c"), + f"{pp2_name}/module2/X64/TestFile2.c", + ) def test_get_relative_path_when_path_does_not_exist(self): - '''Test basic usage of GetEdk2RelativePathFromAbsolutePath with packages path nested + """Test basic usage of GetEdk2RelativePathFromAbsolutePath with packages path nested inside the workspace, but the absolute path is not a real path. File layout: @@ -1090,7 +1104,7 @@ def test_get_relative_path_when_path_does_not_exist(self): module2.inf X64/ TestFile.c - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -1140,7 +1154,7 @@ def test_get_relative_path_when_path_does_not_exist(self): self.assertIsNone(pathobj.GetEdk2RelativePathFromAbsolutePath(*p)) def test_get_relative_path_when_package_is_not_directly_inside_packages_path(self): - '''Test basic usage of GetEdk2RelativePathFromAbsolutePath when the + """Test basic usage of GetEdk2RelativePathFromAbsolutePath when the package is not a direct subfolder of a packagespath, but atleast one folder away. @@ -1152,7 +1166,7 @@ def test_get_relative_path_when_package_is_not_directly_inside_packages_path(sel folder_extra/ PPTestPkg/ <-- A edk2 package PPTestPkg.DEC - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -1170,14 +1184,16 @@ def test_get_relative_path_when_package_is_not_directly_inside_packages_path(sel pathobj = Edk2Path(ws_abs, [folder_pp_abs]) p = os.path.join(ws_pkg_abs, "PPTestPkg.dec") - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), - f"{folder_extra_rel}/{ws_p_name}/{ws_p_name}.dec") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{folder_extra_rel}/{ws_p_name}/{ws_p_name}.dec" + ) p = (ws_pkg_abs, "PPTestPkg.dec") - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(*p), - f"{folder_extra_rel}/{ws_p_name}/{ws_p_name}.dec") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(*p), f"{folder_extra_rel}/{ws_p_name}/{ws_p_name}.dec" + ) def test_get_edk2_relative_path_with_windows_path_on_linux(self): - '''Test basic usage of GetEdk2RelativePathFromAbsolutePath when the + """Test basic usage of GetEdk2RelativePathFromAbsolutePath when the provided path is a Windows path, but the code is running on linux. File layout: @@ -1188,7 +1204,7 @@ def test_get_edk2_relative_path_with_windows_path_on_linux(self): folder_extra/ PPTestPkg/ <-- A edk2 package PPTestPkg.DEC - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -1206,14 +1222,16 @@ def test_get_edk2_relative_path_with_windows_path_on_linux(self): pathobj = Edk2Path(ws_abs, [folder_pp_abs]) p = f"{ws_pkg_abs}\\module2\\X64\\TestFile.c" - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(p), - f"{folder_extra_rel}/PPTestPkg/module2/X64/TestFile.c") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(p), f"{folder_extra_rel}/PPTestPkg/module2/X64/TestFile.c" + ) p = (ws_pkg_abs, "module2", "X64", "TestFile.c") - self.assertEqual(pathobj.GetEdk2RelativePathFromAbsolutePath(*p), - f"{folder_extra_rel}/PPTestPkg/module2/X64/TestFile.c") + self.assertEqual( + pathobj.GetEdk2RelativePathFromAbsolutePath(*p), f"{folder_extra_rel}/PPTestPkg/module2/X64/TestFile.c" + ) def test_get_absolute_path_on_this_system_from_edk2_relative_path(self): - '''Test basic usage of GetAbsolutePathOnThisSystemFromEdk2RelativePath with packages path nested + """Test basic usage of GetAbsolutePathOnThisSystemFromEdk2RelativePath with packages path nested inside the workspace. File layout: @@ -1237,7 +1255,7 @@ def test_get_absolute_path_on_this_system_from_edk2_relative_path(self): module2.inf X64/ TestFile.c - ''' + """ ws_rel = "folder_ws" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -1252,13 +1270,17 @@ def test_get_absolute_path_on_this_system_from_edk2_relative_path(self): # file in packages path ep = os.path.join(pp_pkg_abs, "module1", "module1.INF") - self.assertEqual(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(pp_p_name, "module1", "module1.INF"), ep) + self.assertEqual( + pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(pp_p_name, "module1", "module1.INF"), ep + ) rp = f"{pp_p_name}/module1/module1.INF" self.assertEqual(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(rp), ep) # file in workspace ep = os.path.join(ws_pkg_abs, "module2", "X64", "TestFile.c") - self.assertEqual(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(ws_p_name, "module2", "X64", "TestFile.c"), ep) + self.assertEqual( + pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(ws_p_name, "module2", "X64", "TestFile.c"), ep + ) rp = f"{ws_p_name}/module2/X64/TestFile.c" self.assertEqual(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(rp), ep) @@ -1270,7 +1292,7 @@ def test_get_absolute_path_on_this_system_from_edk2_relative_path(self): self.assertIsNone(pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(None)) def test_get_absolute_path_then_relative_path_when_path_contains_repeated_packagepath_name(self): - '''Test the back and forth between GetAbsolutePath and GetRelativeFromAbsolute when the + """Test the back and forth between GetAbsolutePath and GetRelativeFromAbsolute when the path structure has multiple instances of a package path File layout: root/ <-- current working directory (self.tmp) @@ -1284,7 +1306,7 @@ def test_get_absolute_path_then_relative_path_when_path_contains_repeated_packag module2.INF x64/ TestFile.c. - ''' + """ ws_rel = "PlatformClientPkg" ws_abs = os.path.join(self.tmp, ws_rel) os.mkdir(ws_abs) @@ -1299,12 +1321,12 @@ def test_get_absolute_path_then_relative_path_when_path_contains_repeated_packag pathobj = Edk2Path(ws_abs, [folder_pp1_abs]) # Check getting absolute path from relative path - abspath = pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath( - ws_pkg_name, ws_pkg_name + ".dec") + abspath = pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(ws_pkg_name, ws_pkg_name + ".dec") self.assertEqual(abspath, os.path.join(ws_pkg_abs, "ClientPkg.dec")) abspath = pathobj.GetAbsolutePathOnThisSystemFromEdk2RelativePath( - os.path.join(ws_pkg_name, ws_pkg_name + ".dec")) + os.path.join(ws_pkg_name, ws_pkg_name + ".dec") + ) self.assertEqual(abspath, os.path.join(ws_pkg_abs, "ClientPkg.dec")) # check get relative path from abs path diff --git a/tests.unit/test_status_codes.py b/tests.unit/test_status_codes.py index d48e82fd..66fbc784 100644 --- a/tests.unit/test_status_codes.py +++ b/tests.unit/test_status_codes.py @@ -9,8 +9,7 @@ from edk2toollib.uefi.status_codes import UefiStatusCode -class TestUefiStatusCodes (unittest.TestCase): - +class TestUefiStatusCodes(unittest.TestCase): def test_Hex64ToString_NotError(self): StatusCode = "0x0000000000000000" self.assertEqual(UefiStatusCode().ConvertHexString64ToString(StatusCode), "Success") diff --git a/tests.unit/test_string_handler.py b/tests.unit/test_string_handler.py index 905fb85b..596c441b 100644 --- a/tests.unit/test_string_handler.py +++ b/tests.unit/test_string_handler.py @@ -13,7 +13,6 @@ class TestStringStreamHandler(unittest.TestCase): - def test_init(self): handler = StringStreamHandler() self.assertNotEqual(handler, None) diff --git a/tests.unit/test_tpm2_defs.py b/tests.unit/test_tpm2_defs.py index fd635647..7de9256b 100644 --- a/tests.unit/test_tpm2_defs.py +++ b/tests.unit/test_tpm2_defs.py @@ -11,18 +11,17 @@ class TestCommandCode(unittest.TestCase): - def test_get_code_returns_codes(self): - self.assertEqual(t2d.CommandCode.get_code('TPM_CC_Clear'), 0x00000126) - self.assertEqual(t2d.CommandCode.get_code('TPM_CC_ActivateCredential'), 0x00000147) + self.assertEqual(t2d.CommandCode.get_code("TPM_CC_Clear"), 0x00000126) + self.assertEqual(t2d.CommandCode.get_code("TPM_CC_ActivateCredential"), 0x00000147) def test_get_code_returns_none_if_not_found(self): - self.assertEqual(t2d.CommandCode.get_code('I_AM_NOT_A_VALID_CODE'), None) + self.assertEqual(t2d.CommandCode.get_code("I_AM_NOT_A_VALID_CODE"), None) self.assertEqual(t2d.CommandCode.get_code(None), None) def test_get_string_returns_strings(self): - self.assertEqual(t2d.CommandCode.get_string(0x00000126), 'TPM_CC_Clear') - self.assertEqual(t2d.CommandCode.get_string(0x00000147), 'TPM_CC_ActivateCredential') + self.assertEqual(t2d.CommandCode.get_string(0x00000126), "TPM_CC_Clear") + self.assertEqual(t2d.CommandCode.get_string(0x00000147), "TPM_CC_ActivateCredential") def test_get_string_returns_none_if_not_found(self): self.assertEqual(t2d.CommandCode.get_string(0xFFFFFFFF), None) diff --git a/tests.unit/test_tpm2_policy_calc.py b/tests.unit/test_tpm2_policy_calc.py index 2fade64e..bd32e132 100644 --- a/tests.unit/test_tpm2_policy_calc.py +++ b/tests.unit/test_tpm2_policy_calc.py @@ -11,7 +11,6 @@ class TestPolicyLocality(unittest.TestCase): - def test_create_with_empty_list(self): policy = t2pc.PolicyLocality(None) self.assertEqual(policy.get_bitfield(), 0) @@ -50,7 +49,6 @@ def test_get_buffer(self): class TestPolicyCommandCode(unittest.TestCase): - def test_create_with_no_code(self): with self.assertRaises(ValueError): t2pc.PolicyCommandCode(None) @@ -64,22 +62,24 @@ def test_create_with_invalid_code(self): t2pc.PolicyCommandCode({}) def test_create_with_valid_codes(self): - policy = t2pc.PolicyCommandCode('TPM_CC_Clear') - self.assertEqual(policy.get_code(), 'TPM_CC_Clear') - policy = t2pc.PolicyCommandCode('TPM_CC_ClearControl') - self.assertEqual(policy.get_code(), 'TPM_CC_ClearControl') - policy = t2pc.PolicyCommandCode('TPM_CC_Quote') - self.assertEqual(policy.get_code(), 'TPM_CC_Quote') + policy = t2pc.PolicyCommandCode("TPM_CC_Clear") + self.assertEqual(policy.get_code(), "TPM_CC_Clear") + policy = t2pc.PolicyCommandCode("TPM_CC_ClearControl") + self.assertEqual(policy.get_code(), "TPM_CC_ClearControl") + policy = t2pc.PolicyCommandCode("TPM_CC_Quote") + self.assertEqual(policy.get_code(), "TPM_CC_Quote") def test_get_buffer(self): - self.assertEqual(t2pc.PolicyCommandCode('TPM_CC_Clear').get_buffer_for_digest(), - bytearray.fromhex("0000016C" + "00000126")) - self.assertEqual(t2pc.PolicyCommandCode('TPM_CC_ClearControl').get_buffer_for_digest(), - bytearray.fromhex("0000016C" + "00000127")) + self.assertEqual( + t2pc.PolicyCommandCode("TPM_CC_Clear").get_buffer_for_digest(), bytearray.fromhex("0000016C" + "00000126") + ) + self.assertEqual( + t2pc.PolicyCommandCode("TPM_CC_ClearControl").get_buffer_for_digest(), + bytearray.fromhex("0000016C" + "00000127"), + ) class TestPolicyTreeSolo(unittest.TestCase): - def test_policy_command_code(self): expected_result_1 = bytearray.fromhex("940CFB4217BB1EDCF7FB41937CA974AA68E698AB78B8124B070113E211FD46FC") expected_result_2 = bytearray.fromhex("C4DFABCEDA8DE836C95661952892B1DEF7203AFB46FEFEC43FFCFC93BE540730") @@ -89,7 +89,7 @@ def test_policy_command_code(self): test2 = t2pc.PolicyTreeSolo(t2pc.PolicyCommandCode("TPM_CC_Clear")) test3 = t2pc.PolicyTreeSolo(t2pc.PolicyCommandCode("TPM_CC_NV_UndefineSpaceSpecial")) - policy_hash = t2pc.PolicyHasher('sha256') + policy_hash = t2pc.PolicyHasher("sha256") self.assertEqual(test1.get_policy(policy_hash), expected_result_1) self.assertEqual(test2.get_policy(policy_hash), expected_result_2) self.assertEqual(test3.get_policy(policy_hash), expected_result_3) @@ -99,22 +99,20 @@ def test_policy_locality(self): test = t2pc.PolicyTreeSolo(t2pc.PolicyLocality([3, 4])) - policy_hash = t2pc.PolicyHasher('sha256') + policy_hash = t2pc.PolicyHasher("sha256") self.assertEqual(test.get_policy(policy_hash), expected_result) class TestPolicyTreeAnd(unittest.TestCase): - def test_single_and_should_match_solo(self): soloTest = t2pc.PolicyTreeSolo(t2pc.PolicyCommandCode("TPM_CC_Clear")) andTest = t2pc.PolicyTreeAnd([t2pc.PolicyCommandCode("TPM_CC_Clear")]) - policy_hash = t2pc.PolicyHasher('sha256') + policy_hash = t2pc.PolicyHasher("sha256") self.assertEqual(soloTest.get_policy(policy_hash), andTest.get_policy(policy_hash)) class TestPolicyTreeOr(unittest.TestCase): - def test_single_and_should_match_solo(self): expected_result = bytearray.fromhex("3F44FB41486D4A36A8ADCA2203E73A5068BFED5FDCE5092B9A3C6CCE8ABF3B0C") @@ -122,12 +120,11 @@ def test_single_and_should_match_solo(self): test2 = t2pc.PolicyTreeSolo(t2pc.PolicyCommandCode("TPM_CC_Clear")) orTest = t2pc.PolicyTreeOr([test1, test2]) - policy_hash = t2pc.PolicyHasher('sha256') + policy_hash = t2pc.PolicyHasher("sha256") self.assertEqual(orTest.get_policy(policy_hash), expected_result) class TestPolicyTree(unittest.TestCase): - def test_complex_policy_1(self): expected_result = bytearray.fromhex("DFFDB6C8EAFCBE691E358882B18703121EAB40DE2386F7A8E7B4A06591E1F0EE") @@ -138,16 +135,16 @@ def test_complex_policy_1(self): # policy = {{A} AND {C}} OR {{A} AND {B}} a = t2pc.PolicyLocality([3, 4]) - b = t2pc.PolicyCommandCode('TPM_CC_NV_UndefineSpaceSpecial') - c = t2pc.PolicyCommandCode('TPM_CC_NV_Write') + b = t2pc.PolicyCommandCode("TPM_CC_NV_UndefineSpaceSpecial") + c = t2pc.PolicyCommandCode("TPM_CC_NV_Write") leg1 = t2pc.PolicyTreeAnd([a, c]) leg2 = t2pc.PolicyTreeAnd([a, b]) final = t2pc.PolicyTreeOr([leg1, leg2]) - policy_hash = t2pc.PolicyHasher('sha256') + policy_hash = t2pc.PolicyHasher("sha256") self.assertEqual(final.get_policy(policy_hash), expected_result) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests.unit/test_tpm2_stream.py b/tests.unit/test_tpm2_stream.py index 1d97d621..7e72839c 100644 --- a/tests.unit/test_tpm2_stream.py +++ b/tests.unit/test_tpm2_stream.py @@ -15,20 +15,18 @@ class Tpm2StreamElement(unittest.TestCase): - def test_object_has_zero_size_by_default(self): so = Tpm2Stream.Tpm2StreamElement() self.assertEqual(so.get_size(), 0) class Tpm2CommandHeader(unittest.TestCase): - def test_ch_marshals_correctly(self): ch1 = Tpm2Stream.TPM2_COMMAND_HEADER(0x4321, 0x00000000, 0xDEADBEEF) ch2 = Tpm2Stream.TPM2_COMMAND_HEADER(0x8001, 0x0000000A, Tpm2Defs.TPM_CC_Clear) - self.assertEqual(ch1.marshal(), bytearray.fromhex('432100000000DEADBEEF')) - self.assertEqual(ch2.marshal(), bytearray.fromhex('80010000000A') + struct.pack(">L", Tpm2Defs.TPM_CC_Clear)) + self.assertEqual(ch1.marshal(), bytearray.fromhex("432100000000DEADBEEF")) + self.assertEqual(ch2.marshal(), bytearray.fromhex("80010000000A") + struct.pack(">L", Tpm2Defs.TPM_CC_Clear)) def test_ch_has_correct_size(self): ch1 = Tpm2Stream.TPM2_COMMAND_HEADER(0x4321, 0x00000000, 0xDEADBEEF) @@ -36,6 +34,6 @@ def test_ch_has_correct_size(self): def test_ch_size_can_be_updated(self): ch1 = Tpm2Stream.TPM2_COMMAND_HEADER(0x4321, 0x00000000, 0xDEADBEEF) - self.assertEqual(ch1.marshal(), bytearray.fromhex('432100000000DEADBEEF')) + self.assertEqual(ch1.marshal(), bytearray.fromhex("432100000000DEADBEEF")) ch1.update_size(0x1234) - self.assertEqual(ch1.marshal(), bytearray.fromhex('432100001234DEADBEEF')) + self.assertEqual(ch1.marshal(), bytearray.fromhex("432100001234DEADBEEF")) diff --git a/tests.unit/test_uefi_multi_phase.py b/tests.unit/test_uefi_multi_phase.py index 590f04d6..bbe5dc75 100644 --- a/tests.unit/test_uefi_multi_phase.py +++ b/tests.unit/test_uefi_multi_phase.py @@ -6,17 +6,20 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent ## import unittest -from edk2toollib.uefi.uefi_multi_phase import (EfiVariableAttributes, - EFI_VARIABLE_NON_VOLATILE, EFI_VARIABLE_RUNTIME_ACCESS, - EFI_VARIABLE_BOOTSERVICE_ACCESS, - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) +from edk2toollib.uefi.uefi_multi_phase import ( + EfiVariableAttributes, + EFI_VARIABLE_NON_VOLATILE, + EFI_VARIABLE_RUNTIME_ACCESS, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, +) -class TestUefiMultiphase (unittest.TestCase): - +class TestUefiMultiphase(unittest.TestCase): def test_string_conversion(self): - attributes = EfiVariableAttributes(EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS) + attributes = EfiVariableAttributes( + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS + ) string = str(attributes) self.assertTrue("EFI_VARIABLE_RUNTIME_ACCESS" in string) @@ -30,7 +33,6 @@ def test_empty(self): self.assertEqual(int(attributes), 0) def test_int_to_alternate(self): - attributes = EfiVariableAttributes(EFI_VARIABLE_NON_VOLATILE) self.assertEqual(str(attributes), "EFI_VARIABLE_NON_VOLATILE") self.assertEqual(attributes.get_short_string(), "NV") @@ -41,13 +43,22 @@ def test_int_to_alternate(self): self.assertEqual(attributes.get_short_string(), "BS,NV") self.assertEqual(int(attributes), EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) - attributes.update(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) + attributes.update( + EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS + ) self.assertEqual( - str(attributes), "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_NON_VOLATILE") # noqa + str(attributes), + "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_NON_VOLATILE", + ) # noqa self.assertEqual(attributes.get_short_string(), "AT,BS,NV") - self.assertEqual(int(attributes), EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS - | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) + self.assertEqual( + int(attributes), + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS + | EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS, + ) def test_string_to_alternate(self): attributes = EfiVariableAttributes("EFI_VARIABLE_NON_VOLATILE") @@ -61,12 +72,19 @@ def test_string_to_alternate(self): self.assertEqual(int(attributes), EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) attributes.update( - "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_NON_VOLATILE") # noqa + "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_NON_VOLATILE" + ) # noqa self.assertEqual( - str(attributes), "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_NON_VOLATILE") # noqa + str(attributes), + "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_NON_VOLATILE", + ) # noqa self.assertEqual(attributes.get_short_string(), "AT,BS,NV") - self.assertEqual(int(attributes), EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS - | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) + self.assertEqual( + int(attributes), + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS + | EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS, + ) def test_short_string_to_alternate(self): attributes = EfiVariableAttributes("NV") @@ -81,10 +99,16 @@ def test_short_string_to_alternate(self): attributes.update("AT,BS,NV") self.assertEqual( - str(attributes), "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_NON_VOLATILE") # noqa + str(attributes), + "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,EFI_VARIABLE_BOOTSERVICE_ACCESS,EFI_VARIABLE_NON_VOLATILE", + ) # noqa self.assertEqual(attributes.get_short_string(), "AT,BS,NV") - self.assertEqual(int(attributes), EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS - | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) + self.assertEqual( + int(attributes), + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS + | EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS, + ) def test_with_spaces_to_alternate(self): attributes = EfiVariableAttributes("BS, NV") diff --git a/tests.unit/test_utility_functions.py b/tests.unit/test_utility_functions.py index 7074404d..3275659b 100644 --- a/tests.unit/test_utility_functions.py +++ b/tests.unit/test_utility_functions.py @@ -16,7 +16,7 @@ import pytest -class DesiredClass(): +class DesiredClass: def __str__(self): return "DesiredClass" @@ -31,24 +31,24 @@ def __str__(self): return "GrandChild of DesiredClass" -''' +""" The current solution can't handle a brother class class BrotherOfChildOfDesiredClass(DesiredClass): def __str__(self): return "Brother of Child of DesiredClass" -''' +""" class UtilityFunctionsTest(unittest.TestCase): - def test_RunPythonScript(self): # simple- run yourself! path = __file__ working_dir = os.path.dirname(__file__) ret = utilities.RunPythonScript(path, "", working_dir) self.assertEqual(ret, 0) # test it with all the named parameters - ret = utilities.RunPythonScript(path, "", capture=False, workingdir=working_dir, - raise_exception_on_nonzero=True) + ret = utilities.RunPythonScript( + path, "", capture=False, workingdir=working_dir, raise_exception_on_nonzero=True + ) self.assertEqual(ret, 0) # now try a bad path bad_path = __file__ + ".super.bad" @@ -56,8 +56,9 @@ def test_RunPythonScript(self): # simple- run yourself! self.assertNotEqual(ret, 0) # now we expect it to throw an exception with self.assertRaises(Exception): - ret = utilities.RunPythonScript(bad_path, "", capture=False, workingdir=None, - raise_exception_on_nonzero=True) + ret = utilities.RunPythonScript( + bad_path, "", capture=False, workingdir=None, raise_exception_on_nonzero=True + ) self.assertNotEqual(ret, 0) def test_locate_class_in_module(self): @@ -76,8 +77,8 @@ def test_hexdump_basic_usage(self): test = b"Hello UEFI!" output = io.StringIO() - newline = '\n' - expected_output = f"0x00 - 0x48 0x65 0x6c 0x6c 0x6f 0x20 0x55 0x45 - 0x46 0x49 0x21 Hello UEFI! {newline}" # noqa + newline = "\n" + expected_output = f"0x00 - 0x48 0x65 0x6c 0x6c 0x6f 0x20 0x55 0x45 - 0x46 0x49 0x21 Hello UEFI! {newline}" # noqa utilities.hexdump(test, outfs=output) self.assertEqual(expected_output, output.getvalue()) @@ -86,8 +87,8 @@ def test_hexdump_basic_usage_offset_start(self): test = b"Hello UEFI!" output = io.StringIO() - newline = '\n' - expected_output = f"0x40000000 - 0x48 0x65 0x6c 0x6c 0x6f 0x20 0x55 0x45 - 0x46 0x49 0x21 Hello UEFI! {newline}" # noqa + newline = "\n" + expected_output = f"0x40000000 - 0x48 0x65 0x6c 0x6c 0x6f 0x20 0x55 0x45 - 0x46 0x49 0x21 Hello UEFI! {newline}" # noqa utilities.hexdump(test, offset_start=0x4000_0000, outfs=output) self.assertEqual(expected_output, output.getvalue()) @@ -97,9 +98,9 @@ def test_hexdump_basic_usage_16_bytes(self): test = b"0123456789abcdef" output = io.StringIO() - newline = '\n' + newline = "\n" - expected_output = f"0x00 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa + expected_output = f"0x00 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa utilities.hexdump(test, outfs=output) @@ -110,10 +111,10 @@ def test_hexdump_basic_usage_32_bytes(self): test = b"0123456789abcdef0123456789abcdef" output = io.StringIO() - newline = '\n' + newline = "\n" - expected_output = f"0x40000000 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa - expected_output += f"0x40000010 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa + expected_output = f"0x40000000 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa + expected_output += f"0x40000010 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa utilities.hexdump(test, offset_start=0x4000_0000, outfs=output) @@ -124,10 +125,12 @@ def test_hexdump_basic_usage_33_bytes(self): test = b"0123456789abcdef0123456789abcdef0" output = io.StringIO() - newline = '\n' - expected_output = f"0x00 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa - expected_output += f"0x10 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa - expected_output += f"0x20 - 0x30 0 {newline}" # noqa + newline = "\n" + expected_output = f"0x00 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa + expected_output += f"0x10 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x66 0123456789abcdef {newline}" # noqa + expected_output += ( + f"0x20 - 0x30 0 {newline}" # noqa + ) utilities.hexdump(test, outfs=output) @@ -138,9 +141,9 @@ def test_hexdump_basic_usage_32_bytes_and_line_cont(self): test = b"0123456789abcde\\0123456789abcde\\" output = io.StringIO() - newline = '\n' - expected_output = f"0x00 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x5c 0123456789abcde\\ {newline}" # noqa - expected_output += f"0x10 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x5c 0123456789abcde\\ {newline}" # noqa + newline = "\n" + expected_output = f"0x00 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x5c 0123456789abcde\\ {newline}" # noqa + expected_output += f"0x10 - 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 - 0x38 0x39 0x61 0x62 0x63 0x64 0x65 0x5c 0123456789abcde\\ {newline}" # noqa utilities.hexdump(test, outfs=output) @@ -150,7 +153,7 @@ def test_hexdump_basic_usage_empty(self): """Ensures empty response.""" test = io.BytesIO(b"") output = io.StringIO() - newline = '\n' + newline = "\n" expected_output = f"{newline}" @@ -169,9 +172,9 @@ def test_export_c_type_array_basic_usage(self): test = io.BytesIO(original_bytes) output = io.StringIO() - newline = '\n' + newline = "\n" - expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa + expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa expected_output += f" 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x55, 0x45, 0x46, 0x49, 0x21 // Hello UEFI! {newline}" # noqa expected_output += f"}};{newline*2}" @@ -186,9 +189,9 @@ def test_export_c_type_array_include_length_variable(self): test = io.BytesIO(original_bytes) output = io.StringIO() - newline = '\n' + newline = "\n" - expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa + expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa expected_output += f" 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x55, 0x45, 0x46, 0x49, 0x21 // Hello UEFI! {newline}" # noqa expected_output += f"}};{newline*2}" expected_output += f"UINTN TestVariableLength = sizeof TestVariable;{newline*2}" @@ -204,9 +207,9 @@ def test_export_c_type_array_16_bytes(self): test = io.BytesIO(original_bytes) output = io.StringIO() - newline = '\n' + newline = "\n" - expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa + expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa expected_output += f" 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 // 0123456789abcdef {newline}" # noqa expected_output += f"}};{newline*2}" @@ -221,9 +224,9 @@ def test_export_c_type_array_32_bytes(self): test = io.BytesIO(original_bytes) output = io.StringIO() - newline = '\n' + newline = "\n" - expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa + expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa expected_output += f" 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0123456789abcdef {newline}" # noqa expected_output += f" 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 // 0123456789abcdef {newline}" # noqa expected_output += f"}};{newline*2}" @@ -239,9 +242,9 @@ def test_export_c_type_array_33_bytes(self): test = io.BytesIO(original_bytes) output = io.StringIO() - newline = '\n' + newline = "\n" - expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa + expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa expected_output += f" 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0123456789abcdef {newline}" # noqa expected_output += f" 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0123456789abcdef {newline}" # noqa expected_output += f" 0x30 // 0 {newline}" # noqa @@ -258,9 +261,9 @@ def test_export_c_type_array_32_bytes_and_line_cont(self): test = io.BytesIO(original_bytes) output = io.StringIO() - newline = '\n' + newline = "\n" - expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa + expected_output = f"UINT8 TestVariable[{length}] = {{{newline}" # noqa expected_output += f" 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x5c, // 0123456789abcde\\ {newline}" # noqa expected_output += f" 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x5c // 0123456789abcde\\ {newline}" # noqa expected_output += f"}};{newline*2}" @@ -277,29 +280,35 @@ def test_export_c_type_array_empty(self): with self.assertRaises(ValueError): utilities.export_c_type_array(binary_data, "TestVariable", output) + class TestRemoveTree: """Tests the RemoveTree function.""" - @pytest.mark.skipif(not sys.platform.startswith('win'), reason="Long Paths are only an issue on Windows") + + @pytest.mark.skipif(not sys.platform.startswith("win"), reason="Long Paths are only an issue on Windows") def test_long_path_remove_tree(self, tmp_path): """Tests RemoveTree's ability to remove a directory on a Windows System with LongPaths Disabled.""" import winreg + sub_key = r"SYSTEM\CurrentControlSet\Control\FileSystem" value_name = "LongPathsEnabled" key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, sub_key) value, _ = winreg.QueryValueEx(key, value_name) if value == 1: - pytest.skip(r"Long paths are enabled. To run the test, disable long paths with the registry key located at: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystemLongPathsEnabled") # noqa: E501 + pytest.skip( + r"Long paths are enabled. To run the test, disable long paths with the registry key located at: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystemLongPathsEnabled" + ) # noqa: E501 - long_path = str(tmp_path / ("a" * 250)) # A single folder cannot be longer than 260 characters. - assert len(str(long_path)) > 260 # Make sure the path is actually long. + long_path = str(tmp_path / ("a" * 250)) # A single folder cannot be longer than 260 characters. + assert len(str(long_path)) > 260 # Make sure the path is actually long. # Must use the \\?\ prefix to be able to create a long path when Long Paths are disabled. - os.mkdir('\\\\?\\' + long_path) - with open('\\\\?\\' + long_path + "\\file.txt", "w") as f: + os.mkdir("\\\\?\\" + long_path) + with open("\\\\?\\" + long_path + "\\file.txt", "w") as f: f.write("Hello World!") utilities.RemoveTree(long_path) + # DO NOT PUT A MAIN FUNCTION HERE # this test runs itself to test runpython script, which is a tad bit strange yes. diff --git a/tests.unit/test_variable_format.py b/tests.unit/test_variable_format.py index c103e222..ed2224dd 100644 --- a/tests.unit/test_variable_format.py +++ b/tests.unit/test_variable_format.py @@ -12,7 +12,6 @@ class TestVariableHeader(unittest.TestCase): - def test_set_name(self): var = VF.VariableHeader() @@ -27,5 +26,5 @@ def test_get_packed_name(self): test_name = "MyNewName" var.set_name(test_name) - test_name_packed = bytes.fromhex('4D0079004E00650077004E0061006D0065000000') + test_name_packed = bytes.fromhex("4D0079004E00650077004E0061006D0065000000") self.assertEqual(var.get_packed_name(), test_name_packed) diff --git a/tests.unit/test_variable_policy.py b/tests.unit/test_variable_policy.py index 265c1c38..38e6b01f 100644 --- a/tests.unit/test_variable_policy.py +++ b/tests.unit/test_variable_policy.py @@ -14,17 +14,23 @@ TEST_GUID_1 = uuid.UUID("48B5F961-3F7D-4B88-9BEE-D305ED8256DA") TEST_GUID_2 = uuid.UUID("65D16747-FCBC-4FAE-A727-7B679A7B23F9") -TEST_POLICY_ENTRY = b''.fromhex("000001006A004600E222FFB0EA4A2547A6E55317FB8FD39C00000000FFFFFFFF000000000000000003AFAFAFC690F5ECF9F887438422486E3CCD8B2001AF45004F00440000004C0061007300740041007400740065006D00700074005300740061007400750073000000") # noqa -TEST_POLICY_ENTRY_BAD_VERSION = b''.fromhex("010001006A004600E222FFB0EA4A2547A6E55317FB8FD39C00000000FFFFFFFF000000000000000003AFAFAFC690F5ECF9F887438422486E3CCD8B2001AF45004F00440000004C0061007300740041007400740065006D00700074005300740061007400750073000000") # noqa -TEST_POLICY_ENTRY_BAD_LOCK_TYPE = b''.fromhex("000001006A004600E222FFB0EA4A2547A6E55317FB8FD39C00000000FFFFFFFF000000000000000004AFAFAFC690F5ECF9F887438422486E3CCD8B2001AF45004F00440000004C0061007300740041007400740065006D00700074005300740061007400750073000000") # noqa +TEST_POLICY_ENTRY = b"".fromhex( + "000001006A004600E222FFB0EA4A2547A6E55317FB8FD39C00000000FFFFFFFF000000000000000003AFAFAFC690F5ECF9F887438422486E3CCD8B2001AF45004F00440000004C0061007300740041007400740065006D00700074005300740061007400750073000000" +) # noqa +TEST_POLICY_ENTRY_BAD_VERSION = b"".fromhex( + "010001006A004600E222FFB0EA4A2547A6E55317FB8FD39C00000000FFFFFFFF000000000000000003AFAFAFC690F5ECF9F887438422486E3CCD8B2001AF45004F00440000004C0061007300740041007400740065006D00700074005300740061007400750073000000" +) # noqa +TEST_POLICY_ENTRY_BAD_LOCK_TYPE = b"".fromhex( + "000001006A004600E222FFB0EA4A2547A6E55317FB8FD39C00000000FFFFFFFF000000000000000004AFAFAFC690F5ECF9F887438422486E3CCD8B2001AF45004F00440000004C0061007300740041007400740065006D00700074005300740061007400750073000000" +) # noqa TEST_POLICY_ENTRY_GUID = uuid.UUID("B0FF22E2-4AEA-4725-A6E5-5317FB8FD39C") class TestVariableLockOnVarStatePolicy(unittest.TestCase): def test_remaining_buffer(self): test_vpl = VariableLockOnVarStatePolicy() - test_remainder = b'123' - test_buffer = TEST_GUID_2.bytes_le + b'\x00\x00' + b'\x00A\x00\x00' + test_remainder + test_remainder = b"123" + test_buffer = TEST_GUID_2.bytes_le + b"\x00\x00" + b"\x00A\x00\x00" + test_remainder self.assertEqual(test_remainder, test_vpl.decode(test_buffer)) @@ -32,35 +38,35 @@ def test_missing_name(self): test_vpl = VariableLockOnVarStatePolicy() # Test with no Name field at all. - test1 = TEST_GUID_1.bytes_le + b'\x00\x00' + test1 = TEST_GUID_1.bytes_le + b"\x00\x00" with self.assertRaises(Exception): test_vpl.decode(test1) # Test with an empty string. - test2 = test1 + b'\x00\x00' + test2 = test1 + b"\x00\x00" with self.assertRaises(Exception): test_vpl.decode(test2) # Test successful. - test3 = test1 + b'\x00A\x00\x00' + test3 = test1 + b"\x00A\x00\x00" _ = test_vpl.decode(test3) def test_malformed_name(self): test_vpl = VariableLockOnVarStatePolicy() # Test with no termination. - test1 = TEST_GUID_1.bytes_le + b'\x00\x00' + b'\x00A\x00B' + test1 = TEST_GUID_1.bytes_le + b"\x00\x00" + b"\x00A\x00B" with self.assertRaises(Exception): test_vpl.decode(test1) # Test with an unaligned termination. - test2 = TEST_GUID_1.bytes_le + b'\x00\x00' + b'A\x00B\x00' + b'C' + b'\x00\x00' + test2 = TEST_GUID_1.bytes_le + b"\x00\x00" + b"A\x00B\x00" + b"C" + b"\x00\x00" with self.assertRaises(Exception): test_vpl.decode(test2) def test_to_string(self): test_vpl = VariableLockOnVarStatePolicy() - test_buffer = TEST_GUID_2.bytes_le + b'\x00\x00' + b'A\x00B\x00C\x00\x00\x00' + test_buffer = TEST_GUID_2.bytes_le + b"\x00\x00" + b"A\x00B\x00C\x00\x00\x00" test_vpl.decode(test_buffer) diff --git a/tests.unit/test_wincert.py b/tests.unit/test_wincert.py index b9ddfd07..98efefb6 100644 --- a/tests.unit/test_wincert.py +++ b/tests.unit/test_wincert.py @@ -52,7 +52,6 @@ def test_write_and_from_filestream(self): # write to a filestream with io.BytesIO() as f0, io.BytesIO() as f1, io.BytesIO() as f2: - # Write the data to the first filestream wincert0.write(f0) @@ -111,9 +110,7 @@ def test_write_and_print(self): class WinCertUefiGuidTest(unittest.TestCase): - def test_add_cert_data_raises_exceptions(self): - wincert = WinCertUefiGuid() # Attempt to add Cert Data and capture the error @@ -176,7 +173,7 @@ def test_write_encode_and_decode(self): self.assertTrue(wincert1.encode(), wincert1_encode) def test_add_cert_data(self): - """"Tests add_cert_data, get_certificate, dump_info and string""" + """ "Tests add_cert_data, get_certificate, dump_info and string""" wincert0 = WinCertUefiGuid() # TEST_SIGNATURE_PKCS7 is a signed variable, so we need to remove data we don't need for this test @@ -226,7 +223,6 @@ def test_add_cert_data(self): class WinCertTests(unittest.TestCase): - def test_factory(self): wincert_guid_type = WinCertUefiGuid() # TEST_SIGNATURE_PKCS7 is a signed variable, so we need to remove data we don't need for this test diff --git a/tests.unit/testdata/certificate_blobs.py b/tests.unit/testdata/certificate_blobs.py index 5f395e4f..a96e4d07 100644 --- a/tests.unit/testdata/certificate_blobs.py +++ b/tests.unit/testdata/certificate_blobs.py @@ -8,603 +8,613 @@ ## """Test data for certificate data and authenticated variable related blobs.""" -DEBIAN_CERT = '308202FC308201E4A003020102020500A7468DEF300D06092A864886F70D01010B05003020311E301C060355040313154465' \ - '6269616E2053656375726520426F6F74204341301E170D3136303831363138323235305A170D323630383136313832323530' \ - '5A3024312230200603550403131944656269616E2053656375726520426F6F74205369676E657230820122300D06092A8648' \ - '86F70D01010105000382010F003082010A0282010100D3D183900FDA65A22F075A6095EBF7C7867C2086DA65A3A612EB5B3B' \ - 'CEC8FB3FA1724B9EDF50C50333A40C2B5FD641040DB6CF9548ED8AB2ADD6E501374E60CDB24A3804B3448094AF9F6E54DBA8' \ - '1F3CB74B30DE21816F09A366BA6A2B96D69A61770CD4ED3CD071BBAD8CF0225C3E25CC6D222E619795AF9B2E4D58B67E7802' \ - 'C30EB9FAB25B27DE7DA2BE0C14AC73EC97B0155EEDEDE5A5753F78E071CE2FCE83ED533130984EE6F901A28888A623087C0D' \ - 'B7543A1695ED5E795E904EFECDAADE82FCF696714E4949B9D3E9B0AB7FD72A47B75330277CDC6698096FD17EF57F3D3ED4A2' \ - '6A8859022F2F3DC8C628DE42FED9523D24C2FC409811F676BF8CBB650203010001A3393037301106096086480186F8420101' \ - '04040302041030150603551D25040E300C060A2B0601040182370A0301300B0603551D0F040403020780300D06092A864886' \ - 'F70D01010B05000382010100571BA4604C29E9F27D6B5C93DBCC6C9F183F69489A75DE64F3834A09A92621EEE9565DE13ED9' \ - '75CBCC7FBF4DE4E8893D7E11428740C3D5E07179DC006CE17162C798C2CB270B2F9FCCECFA8BB2F30B9EF3F2C3C99FDB2593' \ - '90A4CDBB01E58EF4D755A8B4754131FD4E5D0318A0C2ACC5DE46E7DC1CCF12D59DE8479D938C32CD44D574C7309A57A556D0' \ - '7ECF0511B4F4F329F9DB9B53D2BD2FAD6A75264564BABA2896878EB7F07957FA7A0E3C4A3892BCF295F2E728D0F7D8981A5E' \ - '399EB56580BDF3DA123F507667299FD10B0A1E87975C72DBF301744ADD07BA76E96AFCDD22DB4602D7AF0AC5ED15BC0F2BA9' \ - 'DB8DBF7F6FADA2B7C54D4A47B3C15690B617' +DEBIAN_CERT = ( + "308202FC308201E4A003020102020500A7468DEF300D06092A864886F70D01010B05003020311E301C060355040313154465" + "6269616E2053656375726520426F6F74204341301E170D3136303831363138323235305A170D323630383136313832323530" + "5A3024312230200603550403131944656269616E2053656375726520426F6F74205369676E657230820122300D06092A8648" + "86F70D01010105000382010F003082010A0282010100D3D183900FDA65A22F075A6095EBF7C7867C2086DA65A3A612EB5B3B" + "CEC8FB3FA1724B9EDF50C50333A40C2B5FD641040DB6CF9548ED8AB2ADD6E501374E60CDB24A3804B3448094AF9F6E54DBA8" + "1F3CB74B30DE21816F09A366BA6A2B96D69A61770CD4ED3CD071BBAD8CF0225C3E25CC6D222E619795AF9B2E4D58B67E7802" + "C30EB9FAB25B27DE7DA2BE0C14AC73EC97B0155EEDEDE5A5753F78E071CE2FCE83ED533130984EE6F901A28888A623087C0D" + "B7543A1695ED5E795E904EFECDAADE82FCF696714E4949B9D3E9B0AB7FD72A47B75330277CDC6698096FD17EF57F3D3ED4A2" + "6A8859022F2F3DC8C628DE42FED9523D24C2FC409811F676BF8CBB650203010001A3393037301106096086480186F8420101" + "04040302041030150603551D25040E300C060A2B0601040182370A0301300B0603551D0F040403020780300D06092A864886" + "F70D01010B05000382010100571BA4604C29E9F27D6B5C93DBCC6C9F183F69489A75DE64F3834A09A92621EEE9565DE13ED9" + "75CBCC7FBF4DE4E8893D7E11428740C3D5E07179DC006CE17162C798C2CB270B2F9FCCECFA8BB2F30B9EF3F2C3C99FDB2593" + "90A4CDBB01E58EF4D755A8B4754131FD4E5D0318A0C2ACC5DE46E7DC1CCF12D59DE8479D938C32CD44D574C7309A57A556D0" + "7ECF0511B4F4F329F9DB9B53D2BD2FAD6A75264564BABA2896878EB7F07957FA7A0E3C4A3892BCF295F2E728D0F7D8981A5E" + "399EB56580BDF3DA123F507667299FD10B0A1E87975C72DBF301744ADD07BA76E96AFCDD22DB4602D7AF0AC5ED15BC0F2BA9" + "DB8DBF7F6FADA2B7C54D4A47B3C15690B617" +) -UBUNTU_CERT = '3082042030820308A003020102020101300D06092A864886F70D01010B0500308184310B3009060355040613024742311430' \ - '1206035504080C0B49736C65206F66204D616E3110300E06035504070C07446F75676C617331173015060355040A0C0E4361' \ - '6E6F6E6963616C204C74642E3134303206035504030C2B43616E6F6E6963616C204C74642E204D6173746572204365727469' \ - '66696361746520417574686F72697479301E170D3132303431323131333930385A170D3432303431313131333930385A307F' \ - '310B30090603550406130247423114301206035504080C0B49736C65206F66204D616E31173015060355040A0C0E43616E6F' \ - '6E6963616C204C74642E31143012060355040B0C0B53656375726520426F6F74312B302906035504030C2243616E6F6E6963' \ - '616C204C74642E2053656375726520426F6F74205369676E696E6730820122300D06092A864886F70D01010105000382010F' \ - '003082010A0282010100C95F9B628F0BB06482ACBEC9E262E34BD29F1E8AD5611A2B5D38F4B7CEB99AB843B8439777AB4F7F' \ - '0C70460BFC7F6DC66DEA805E01D2B7661E87DE0D6DD04197A8A5AF0C634FF77CC252CCA031A9BB895D991E466F5573B97669' \ - 'ECD7C1FC21D6C607E74FBD22DEE4A85B2DDB95341997D6284B214CCABB1D79A6177F5AF967E65C78453D106DB017592611C5' \ - '57E37F4E82BAF62C4EC8374DFF85158447E0ED3B7C7FBCAFE90105A70C6FC3E98DA3CEBEA6E3CD3CB5582C9EC2031C602237' \ - '39FF4102C129A46551FF3334AA4215F99578FC2DF5DA8A857C829DFB372C6BA5A8DF7C550B802E3CB063E1CD384889E81406' \ - '0B82BCFDD407681B0F3ED915DD94111B0203010001A381A030819D300C0603551D130101FF04023000301F0603551D250418' \ - '301606082B06010505070303060A2B0601040182370A0306302C06096086480186F842010D041F161D4F70656E53534C2047' \ - '656E657261746564204365727469666963617465301D0603551D0E0416041461482AA2830D0AB2AD5AF10B7250DA9033DDCE' \ - 'F0301F0603551D23041830168014AD91990BC22AB1F517048C23B6655A268E345A63300D06092A864886F70D01010B050003' \ - '820101008F8AA1061F29B70A4AD5C5FD81AB25EAC07DE2FC6A96A0799367EE050E251225E45AF6AA1AF112F3058D875EF15A' \ - '5CCB8D2373651D15B9DE226BD64967C9A3C6D7624E5CB5F903834081DC879C3C3F1C0D519F94650A844867E4A2F8A64AF0E7' \ - 'CDCDBD94E309D25D2D161B05150BCB44B43E614222C42A5C4EC51DA3E2E052B2EBF48B2BDC38395DFB88A156655F2B4F26FF' \ - '06781012EB8C5D32E3C645AF259BA0FF8EEF4709A3E98B37929269767E343B9205674EB025EDBC5E5F8FB4D6CA40FFE4E231' \ - '230C8525AE0C5501ECE5475EDF5BBC1433E3C6F518B6D9F7DDB3B4A131D35A5C5D7D3EBF0AE4E4E8B4597D3BB48CA31BB520' \ - 'A3B93E846F8C2100C339' +UBUNTU_CERT = ( + "3082042030820308A003020102020101300D06092A864886F70D01010B0500308184310B3009060355040613024742311430" + "1206035504080C0B49736C65206F66204D616E3110300E06035504070C07446F75676C617331173015060355040A0C0E4361" + "6E6F6E6963616C204C74642E3134303206035504030C2B43616E6F6E6963616C204C74642E204D6173746572204365727469" + "66696361746520417574686F72697479301E170D3132303431323131333930385A170D3432303431313131333930385A307F" + "310B30090603550406130247423114301206035504080C0B49736C65206F66204D616E31173015060355040A0C0E43616E6F" + "6E6963616C204C74642E31143012060355040B0C0B53656375726520426F6F74312B302906035504030C2243616E6F6E6963" + "616C204C74642E2053656375726520426F6F74205369676E696E6730820122300D06092A864886F70D01010105000382010F" + "003082010A0282010100C95F9B628F0BB06482ACBEC9E262E34BD29F1E8AD5611A2B5D38F4B7CEB99AB843B8439777AB4F7F" + "0C70460BFC7F6DC66DEA805E01D2B7661E87DE0D6DD04197A8A5AF0C634FF77CC252CCA031A9BB895D991E466F5573B97669" + "ECD7C1FC21D6C607E74FBD22DEE4A85B2DDB95341997D6284B214CCABB1D79A6177F5AF967E65C78453D106DB017592611C5" + "57E37F4E82BAF62C4EC8374DFF85158447E0ED3B7C7FBCAFE90105A70C6FC3E98DA3CEBEA6E3CD3CB5582C9EC2031C602237" + "39FF4102C129A46551FF3334AA4215F99578FC2DF5DA8A857C829DFB372C6BA5A8DF7C550B802E3CB063E1CD384889E81406" + "0B82BCFDD407681B0F3ED915DD94111B0203010001A381A030819D300C0603551D130101FF04023000301F0603551D250418" + "301606082B06010505070303060A2B0601040182370A0306302C06096086480186F842010D041F161D4F70656E53534C2047" + "656E657261746564204365727469666963617465301D0603551D0E0416041461482AA2830D0AB2AD5AF10B7250DA9033DDCE" + "F0301F0603551D23041830168014AD91990BC22AB1F517048C23B6655A268E345A63300D06092A864886F70D01010B050003" + "820101008F8AA1061F29B70A4AD5C5FD81AB25EAC07DE2FC6A96A0799367EE050E251225E45AF6AA1AF112F3058D875EF15A" + "5CCB8D2373651D15B9DE226BD64967C9A3C6D7624E5CB5F903834081DC879C3C3F1C0D519F94650A844867E4A2F8A64AF0E7" + "CDCDBD94E309D25D2D161B05150BCB44B43E614222C42A5C4EC51DA3E2E052B2EBF48B2BDC38395DFB88A156655F2B4F26FF" + "06781012EB8C5D32E3C645AF259BA0FF8EEF4709A3E98B37929269767E343B9205674EB025EDBC5E5F8FB4D6CA40FFE4E231" + "230C8525AE0C5501ECE5475EDF5BBC1433E3C6F518B6D9F7DDB3B4A131D35A5C5D7D3EBF0AE4E4E8B4597D3BB48CA31BB520" + "A3B93E846F8C2100C339" +) HASHSTR = [ - '0000000000000000000000000000000000000000000000000000000000000000', - '1111111111111111111111111111111111111111111111111111111111111111', - '2222222222222222222222222222222222222222222222222222222222222222', - '3333333333333333333333333333333333333333333333333333333333333333', - '4444444444444444444444444444444444444444444444444444444444444444', - '5555555555555555555555555555555555555555555555555555555555555555', - '6666666666666666666666666666666666666666666666666666666666666666', - '7777777777777777777777777777777777777777777777777777777777777777', - '8888888888888888888888888888888888888888888888888888888888888888', - '9999999999999999999999999999999999999999999999999999999999999999' + "0000000000000000000000000000000000000000000000000000000000000000", + "1111111111111111111111111111111111111111111111111111111111111111", + "2222222222222222222222222222222222222222222222222222222222222222", + "3333333333333333333333333333333333333333333333333333333333333333", + "4444444444444444444444444444444444444444444444444444444444444444", + "5555555555555555555555555555555555555555555555555555555555555555", + "6666666666666666666666666666666666666666666666666666666666666666", + "7777777777777777777777777777777777777777777777777777777777777777", + "8888888888888888888888888888888888888888888888888888888888888888", + "9999999999999999999999999999999999999999999999999999999999999999", ] # DBXFILE contains Dbx contents downloaded from UEFI.org's Revocation List on 2022.01.30 (x64) -DBXFILE = "da070306131115000000000000000000f60c00000002f10e9dd2af4adf68ee498aa9347d375665a7" \ - "30820cda020101310f300d06096086480165030402010500300b06092a864886f70d010701a0820a" \ - "ed308204fd308203e5a0030201020213330000002596d20c5c53120043000000000025300d06092a" \ - "864886f70d01010b0500308180310b3009060355040613025553311330110603550408130a576173" \ - "68696e67746f6e3110300e060355040713075265646d6f6e64311e301c060355040a13154d696372" \ - "6f736f667420436f72706f726174696f6e312a3028060355040313214d6963726f736f667420436f" \ - "72706f726174696f6e204b454b2043412032303131301e170d3231303930323138323433315a170d" \ - "3232303930313138323433315a308186310b3009060355040613025553311330110603550408130a" \ - "57617368696e67746f6e3110300e060355040713075265646d6f6e64311e301c060355040a13154d" \ - "6963726f736f667420436f72706f726174696f6e3130302e060355040313274d6963726f736f6674" \ - "2057696e646f77732055454649204b65792045786368616e6765204b657930820122300d06092a86" \ - "4886f70d01010105000382010f003082010a0282010100cabe8aef9b0f8692546db68e66e1585f14" \ - "ebebe6eed227c8fa323674b22e24efbafa169e7a5fa4c2e6f252076ab245a4f8cf358d0d9c618caf" \ - "ae8ad1807cd50c1923a741a3525a4e32e78d21b83b06351703349de5635e77b2ac3e502fb7231c59" \ - "e3f3c977139eeb65e44324f6cf04701fd5962995d0f573012769eea20942a7bec1f7e67d4b2e6ed8" \ - "a958a98e4043aa6f620b676becebab447f6ecbf174fda343ba10cbfc1e05c2d652d3a139626f4a18" \ - "e7f8bf3fa412f63fc13af332040049d2b26ea270c5cf914f56661de0d54ce3bc3399e01e016190a0" \ - "3dc8826a87b032e01526dadd767ef07c0ba72953d021115f87264bf21c6cb8dbe6c7f067087cb702" \ - "03010001a38201663082016230140603551d25040d300b06092b0601040182374f01301d0603551d" \ - "0e04160414753d9cab3265b73cafcc22f9b16ba1e38dcf8d6130450603551d11043e303ca43a3038" \ - "311e301c060355040b13154d6963726f736f667420436f72706f726174696f6e3116301406035504" \ - "05130d3232393936312b343637353933301f0603551d2304183016801462fc43cda03ea4cb6712d2" \ - "5bd955ac7bccb68a5f30530603551d1f044c304a3048a046a0448642687474703a2f2f7777772e6d" \ - "6963726f736f66742e636f6d2f706b696f70732f63726c2f4d6963436f724b454b4341323031315f" \ - "323031312d30362d32342e63726c306006082b0601050507010104543052305006082b0601050507" \ - "30028644687474703a2f2f7777772e6d6963726f736f66742e636f6d2f706b696f70732f63657274" \ - "732f4d6963436f724b454b4341323031315f323031312d30362d32342e637274300c0603551d1301" \ - "01ff04023000300d06092a864886f70d01010b0500038201010069662ba664b30e7f47e3308e9cbf" \ - "0f6c1250bd8eecd227c8a223c5ced041a35bef9d8aa41a31ceee757163a15d4fdc921518daa17087" \ - "3922e85324a6d2a7c2a74b483a488f7ef0262324568d63914a9d66915ee9f6a4c1c0f07592689c16" \ - "833a87006ce0f650b15314b0f4f3bb0b3d623db77a4d526e8dc1d9358f2a3a6a76661a41677f4d00" \ - "a2979e8493e27106e3b5414d11dc91d0c0dbe83ea3b188959b48889350293669c8bf9315b34d2aae" \ - "0f64b78e36051c341cde7d77ec06aa47c6aa35f0bf6f36455fbc17c431b6048bc2003c88b48f04b3" \ - "52da0fbef900a2f20262d867a54d4dd841605e1d4b0024d46f6c79cd4fd5b3c022107ac921ed71e0" \ - "8a59308205e8308203d0a003020102020a610ad188000000000003300d06092a864886f70d01010b" \ - "0500308191310b3009060355040613025553311330110603550408130a57617368696e67746f6e31" \ - "10300e060355040713075265646d6f6e64311e301c060355040a13154d6963726f736f667420436f" \ - "72706f726174696f6e313b3039060355040313324d6963726f736f667420436f72706f726174696f" \ - "6e205468697264205061727479204d61726b6574706c61636520526f6f74301e170d313130363234" \ - "3230343132395a170d3236303632343230353132395a308180310b30090603550406130255533113" \ - "30110603550408130a57617368696e67746f6e3110300e060355040713075265646d6f6e64311e30" \ - "1c060355040a13154d6963726f736f667420436f72706f726174696f6e312a302806035504031321" \ - "4d6963726f736f667420436f72706f726174696f6e204b454b204341203230313130820122300d06" \ - "092a864886f70d01010105000382010f003082010a0282010100c4e8b58abfad5726b026c3eae7fb" \ - "577a44025d070dda4ae5742ae6b00fec6debec7fb9e35a63327c11174f0ee30ba73815938ec6f5e0" \ - "84b19a9b2ce7f5b791d609e1e2c004a8ac301cdf48f306509a64a7517fc8854f8f2086cefe2fe19f" \ - "ff82c0ede9cdcef4536a623a0b43b9e225fdfe05f9d4c414ab11e223898d70b7a41d4decaee59cfa" \ - "16c2d7c1cbd4e8c42fe599ee248b03ec8df28beac34afb4311120b7eb547926cdce60489ebf53304" \ - "eb10012a71e5f983133cff25092f687646ffba4fbedcad712a58aafb0ed2793de49b653bcc292a9f" \ - "fc7259a2ebae92eff6351380c602ece45fcc9d76cdef6392c1af79408479877fe352a8e89d7b0769" \ - "8f150203010001a382014f3082014b301006092b06010401823715010403020100301d0603551d0e" \ - "0416041462fc43cda03ea4cb6712d25bd955ac7bccb68a5f301906092b0601040182371402040c1e" \ - "0a00530075006200430041300b0603551d0f040403020186300f0603551d130101ff040530030101" \ - "ff301f0603551d2304183016801445665243e17e5811bfd64e9e2355083b3a226aa8305c0603551d" \ - "1f045530533051a04fa04d864b687474703a2f2f63726c2e6d6963726f736f66742e636f6d2f706b" \ - "692f63726c2f70726f64756374732f4d6963436f725468695061724d6172526f6f5f323031302d31" \ - "302d30352e63726c306006082b0601050507010104543052305006082b0601050507300286446874" \ - "74703a2f2f7777772e6d6963726f736f66742e636f6d2f706b692f63657274732f4d6963436f7254" \ - "68695061724d6172526f6f5f323031302d31302d30352e637274300d06092a864886f70d01010b05" \ - "000382020100d48488f514941802ca2a3cfb2a921c0cd7a0d1f1e85266a8eea2b5757a9000aa2da4" \ - "765aea79b7b9376a517b1064f6e164f20267bef7a81b78bdbace8858640cd657c819a35f05d6dbc6" \ - "d069ce484b32b7eb5dd230f5c0f5b8ba7807a32bfe9bdb345684ec82caae4125709c6be9fe900fd7" \ - "961fe5e7941fb22a0c8d4bff2829107bf7d77ca5d176b905c879ed0f90929cc2fedf6f7e6c0f7bd4" \ - "c145dd345196390fe55e56d8180596f407a642b3a077fd0819f27156cc9f8623a487cba6fd587ed4" \ - "696715917e81f27f13e50d8b8a3c8784ebe3cebd43e5ad2d84938e6a2b5a7c44fa52aa81c82d1cbb" \ - "e052df0011f89a3dc160b0e133b5a388d165190a1ae7ac7ca4c182874e38b12f0dc514876ffd8d2e" \ - "bc39b6e7e6c3e0e4cd2784ef9442ef298b9046413b811b67d8f9435965cb0dbcfd00924ff4753ba7" \ - "a924fc50414079e02d4f0a6a27766e52ed96697baf0ff78705d045c2ad5314811ffb3004aa373661" \ - "da4a691b34d868edd602cf6c940cd3cf6c2279adb1f0bc03a24660a9c407c22182f1fdf2e8793260" \ - "bfd8aca522144bcac1d84beb7d3f5735b2e64f75b4b060032253ae91791dd69b411f15865470b2de" \ - "0d350f7cb03472ba97603bf079eba2b21c5da216b887c5e91bf6b597256f389fe391fa8a7998c369" \ - "0eb7a31c200597f8ca14ae00d7c4f3c01410756b34a01bb59960f35cb0c5574e36d23284bf9e3182" \ - "01c4308201c0020101308198308180310b3009060355040613025553311330110603550408130a57" \ - "617368696e67746f6e3110300e060355040713075265646d6f6e64311e301c060355040a13154d69" \ - "63726f736f667420436f72706f726174696f6e312a3028060355040313214d6963726f736f667420" \ - "436f72706f726174696f6e204b454b20434120323031310213330000002596d20c5c531200430000" \ - "00000025300d06096086480165030402010500300d06092a864886f70d01010105000482010002fc" \ - "f6d3fb1c3e7af2bff3a028b0d2ddace519e9d3bf9eaccc0b89e69ba782e42a6b7b723cbca7f93130" \ - "b79053db51f5c9e30b0607cb6144170a1e2053ba1edd1553c44cf694c094e594e904d341d157789a" \ - "cebbf327b52a9027113195403625a47137dc8d779414d3cf434d0077d61de393a960f1525bbb8c90" \ - "b6db9ffa1763bffc50e9f89a33c8a58fc3af6a6174d18ee42b60b32ed0edf014124e0cb65943b573" \ - "b72b9c36b837b686f1026874428c6b61cb6fec305fd51dde53b32ead7575d8a9b8de4079d6476b16" \ - "db7d1b029ad59f76a1ed7b532d05e50870eb873cd86c843b19a9e2ae412ad0f1c768802626098dc8" \ - "e1513529e6c7e062801e1ee7daa02616c4c14c509240aca941f936934328cc280000000000003000" \ - "0000bd9afa775903324dbd6028f4e78f784b80b4d96931bf0d02fd91a61e19d14f1da452e66db240" \ - "8ca8604d411f92659f0abd9afa775903324dbd6028f4e78f784bf52f83a3fa9cfbd6920f722824db" \ - "e4034534d25b8507246b3b957dac6e1bce7abd9afa775903324dbd6028f4e78f784bc5d9d8a186e2" \ - "c82d09afaa2a6f7f2e73870d3e64f72c4e08ef67796a840f0fbdbd9afa775903324dbd6028f4e78f" \ - "784b1aec84b84b6c65a51220a9be7181965230210d62d6d33c48999c6b295a2b0a06bd9afa775903" \ - "324dbd6028f4e78f784bc3a99a460da464a057c3586d83cef5f4ae08b7103979ed8932742df0ed53" \ - "0c66bd9afa775903324dbd6028f4e78f784b58fb941aef95a25943b3fb5f2510a0df3fe44c58c95e" \ - "0ab80487297568ab9771bd9afa775903324dbd6028f4e78f784b5391c3a2fb112102a6aa1edc25ae" \ - "77e19f5d6f09cd09eeb2509922bfcd5992eabd9afa775903324dbd6028f4e78f784bd626157e1d6a" \ - "718bc124ab8da27cbb65072ca03a7b6b257dbdcbbd60f65ef3d1bd9afa775903324dbd6028f4e78f" \ - "784bd063ec28f67eba53f1642dbf7dff33c6a32add869f6013fe162e2c32f1cbe56dbd9afa775903" \ - "324dbd6028f4e78f784b29c6eb52b43c3aa18b2cd8ed6ea8607cef3cfae1bafe1165755cf2e61484" \ - "4a44bd9afa775903324dbd6028f4e78f784b90fbe70e69d633408d3e170c6832dbb2d209e0272527" \ - "dfb63d49d29572a6f44cbd9afa775903324dbd6028f4e78f784b106faceacfecfd4e303b74f480a0" \ - "8098e2d0802b936f8ec774ce21f31686689cbd9afa775903324dbd6028f4e78f784b174e3a0b5b43" \ - "c6a607bbd3404f05341e3dcf396267ce94f8b50e2e23a9da920cbd9afa775903324dbd6028f4e78f" \ - "784b2b99cf26422e92fe365fbf4bc30d27086c9ee14b7a6fff44fb2f6b9001699939bd9afa775903" \ - "324dbd6028f4e78f784b2e70916786a6f773511fa7181fab0f1d70b557c6322ea923b2a8d3b92b51" \ - "af7dbd9afa775903324dbd6028f4e78f784b3fce9b9fdf3ef09d5452b0f95ee481c2b7f06d743a73" \ - "7971558e70136ace3e73bd9afa775903324dbd6028f4e78f784b47cc086127e2069a86e03a6bef2c" \ - "d410f8c55a6d6bdb362168c31b2ce32a5adfbd9afa775903324dbd6028f4e78f784b71f2906fd222" \ - "497e54a34662ab2497fcc81020770ff51368e9e3d9bfcbfd6375bd9afa775903324dbd6028f4e78f" \ - "784b82db3bceb4f60843ce9d97c3d187cd9b5941cd3de8100e586f2bda5637575f67bd9afa775903" \ - "324dbd6028f4e78f784b8ad64859f195b5f58dafaa940b6a6167acd67a886e8f469364177221c559" \ - "45b9bd9afa775903324dbd6028f4e78f784b8d8ea289cfe70a1c07ab7365cb28ee51edd33cf2506d" \ - "e888fbadd60ebf80481cbd9afa775903324dbd6028f4e78f784baeebae3151271273ed95aa2e6711" \ - "39ed31a98567303a332298f83709a9d55aa1bd9afa775903324dbd6028f4e78f784bc409bdac4775" \ - "add8db92aa22b5b718fb8c94a1462c1fe9a416b95d8a3388c2fcbd9afa775903324dbd6028f4e78f" \ - "784bc617c1a8b1ee2a811c28b5a81b4c83d7c98b5b0c27281d610207ebe692c2967fbd9afa775903" \ - "324dbd6028f4e78f784bc90f336617b8e7f983975413c997f10b73eb267fd8a10cb9e3bdbfc667ab" \ - "db8bbd9afa775903324dbd6028f4e78f784b64575bd912789a2e14ad56f6341f52af6bf80cf94400" \ - "785975e9f04e2d64d745bd9afa775903324dbd6028f4e78f784b45c7c8ae750acfbb48fc37527d64" \ - "12dd644daed8913ccd8a24c94d856967df8ebd9afa775903324dbd6028f4e78f784b81d8fb4c9e2e" \ - "7a8225656b4b8273b7cba4b03ef2e9eb20e0a0291624eca1ba86bd9afa775903324dbd6028f4e78f" \ - "784bb92af298dc08049b78c77492d6551b710cd72aada3d77be54609e43278ef6e4dbd9afa775903" \ - "324dbd6028f4e78f784be19dae83c02e6f281358d4ebd11d7723b4f5ea0e357907d5443decc5f93c" \ - "1e9dbd9afa775903324dbd6028f4e78f784b39dbc2288ef44b5f95332cb777e31103e840dba68063" \ - "4aa806f5c9b100061802bd9afa775903324dbd6028f4e78f784b32f5940ca29dd812a2c145e6fc89" \ - "646628ffcc7c7a42cae512337d8d29c40bbdbd9afa775903324dbd6028f4e78f784b10d45fcba396" \ - "aef3153ee8f6ecae58afe8476a280a2026fc71f6217dcf49ba2fbd9afa775903324dbd6028f4e78f" \ - "784b4b8668a5d465bcdd9000aa8dfcff42044fcbd0aece32fc7011a83e9160e89f09bd9afa775903" \ - "324dbd6028f4e78f784b89f3d1f6e485c334cd059d0995e3cdfdc00571b1849854847a44dc5548e2" \ - "dcfbbd9afa775903324dbd6028f4e78f784bc9ec350406f26e559affb4030de2ebde5435054c35a9" \ - "98605b8fcf04972d8d55bd9afa775903324dbd6028f4e78f784bb3e506340fbf6b5786973393079f" \ - "24b66ba46507e35e911db0362a2acde97049bd9afa775903324dbd6028f4e78f784b9f1863ed5717" \ - "c394b42ef10a6607b144a65ba11fb6579df94b8eb2f0c4cd60c1bd9afa775903324dbd6028f4e78f" \ - "784bdd59af56084406e38c63fbe0850f30a0cd1277462a2192590fb05bc259e61273bd9afa775903" \ - "324dbd6028f4e78f784bdbaf9e056d3d5b38b68553304abc88827ebc00f80cb9c7e197cdbc5822cd" \ - "316cbd9afa775903324dbd6028f4e78f784b65f3c0a01b8402d362b9722e98f75e5e991e6c186e93" \ - "4f7b2b2e6be6dec800ecbd9afa775903324dbd6028f4e78f784b5b248e913d71853d3da5aedd8d9a" \ - "4bc57a917126573817fb5fcb2d86a2f1c886bd9afa775903324dbd6028f4e78f784b2679650fe341" \ - "f2cf1ea883460b3556aaaf77a70d6b8dc484c9301d1b746cf7b5bd9afa775903324dbd6028f4e78f" \ - "784bbb1dd16d530008636f232303a7a86f3dff969f848815c0574b12c2d787fec93fbd9afa775903" \ - "324dbd6028f4e78f784b0ce02100f67c7ef85f4eed368f02bf7092380a3c23ca91fd7f19430d94b0" \ - "0c19bd9afa775903324dbd6028f4e78f784b95049f0e4137c790b0d2767195e56f73807d123adcf8" \ - "f6e7bf2d4d991d305f89bd9afa775903324dbd6028f4e78f784b02e6216acaef6401401fa555ecbe" \ - "d940b1a5f2569aed92956137ae58482ef1b7bd9afa775903324dbd6028f4e78f784b6efefe0b5b01" \ - "478b7b944c10d3a8aca2cca4208888e2059f8a06cb5824d7bab0bd9afa775903324dbd6028f4e78f" \ - "784b9d00ae4cd47a41c783dc48f342c076c2c16f3413f4d2df50d181ca3bb5ad859dbd9afa775903" \ - "324dbd6028f4e78f784bd8d4e6ddf6e42d74a6a536ea62fd1217e4290b145c9e5c3695a31b42efb5" \ - "f5a4bd9afa775903324dbd6028f4e78f784bf277af4f9bdc918ae89fa35cc1b34e34984c04ae9765" \ - "322c3cb049574d36509cbd9afa775903324dbd6028f4e78f784b0dc24c75eb1aef56b9f13ab9de60" \ - "e2eca1c4510034e290bbb36cf60a549b234cbd9afa775903324dbd6028f4e78f784b835881f2a557" \ - "2d7059b5c8635018552892e945626f115fc9ca07acf7bde857a4bd9afa775903324dbd6028f4e78f" \ - "784bbadff5e4f0fea711701ca8fb22e4c43821e31e210cf52d1d4f74dd50f1d039bcbd9afa775903" \ - "324dbd6028f4e78f784bc452ab846073df5ace25cca64d6b7a09d906308a1a65eb5240e3c4ebcaa9" \ - "cc0cbd9afa775903324dbd6028f4e78f784bf1863ec8b7f43f94ad14fb0b8b4a69497a8c65ecbc2a" \ - "55e0bb420e772b8cdc91bd9afa775903324dbd6028f4e78f784b7bc9cb5463ce0f011fb5085eb8ba" \ - "77d1acd283c43f4a57603cc113f22cebc579bd9afa775903324dbd6028f4e78f784be800395dbe0e" \ - "045781e8005178b4baf5a257f06e159121a67c595f6ae22506fdbd9afa775903324dbd6028f4e78f" \ - "784b1cb4dccaf2c812cfa7b4938e1371fe2b96910fe407216fd95428672d6c7e7316bd9afa775903" \ - "324dbd6028f4e78f784b3ece27cbb3ec4438cce523b927c4f05fdc5c593a3766db984c5e437a3ff6" \ - "a16bbd9afa775903324dbd6028f4e78f784b68ee4632c7be1c66c83e89dd93eaee1294159abf45b4" \ - "c2c72d7dc7499aa2a043bd9afa775903324dbd6028f4e78f784be24b315a551671483d8b9073b32d" \ - "e11b4de1eb2eab211afd2d9c319ff55e08d0bd9afa775903324dbd6028f4e78f784be7c20b3ab481" \ - "ec885501eca5293781d84b5a1ac24f88266b5270e7ecb4aa2538bd9afa775903324dbd6028f4e78f" \ - "784bdccc3ce1c00ee4b0b10487d372a0fa47f5c26f57a359be7b27801e144eacbac4bd9afa775903" \ - "324dbd6028f4e78f784b0257ff710f2a16e489b37493c07604a7cda96129d8a8fd68d2b6af633904" \ - "315dbd9afa775903324dbd6028f4e78f784b3a91f0f9e5287fa2994c7d930b2c1a5ee14ce8e1c830" \ - "4ae495adc58cc4453c0cbd9afa775903324dbd6028f4e78f784b495300790e6c9bf2510daba59db3" \ - "d57e9d2b85d7d7640434ec75baa3851c74e5bd9afa775903324dbd6028f4e78f784b81a8b2c9751a" \ - "eb1faba7dbde5ee9691dc0eaee2a31c38b1491a8146756a6b770bd9afa775903324dbd6028f4e78f" \ - "784b8e53efdc15f852cee5a6e92931bc42e6163cd30ff649cca7e87252c3a459960bbd9afa775903" \ - "324dbd6028f4e78f784b992d359aa7a5f789d268b94c11b9485a6b1ce64362b0edb4441ccc187c39" \ - "647bbd9afa775903324dbd6028f4e78f784b9fa4d5023fd43ecaff4200ba7e8d4353259d2b7e5e72" \ - "b5096eff8027d66d1043bd9afa775903324dbd6028f4e78f784bd372c0d0f4fdc9f52e9e1f23fc56" \ - "ee72414a17f350d0cea6c26a35a6c3217a13bd9afa775903324dbd6028f4e78f784b5c5805196a85" \ - "e93789457017d4f9eb6828b97c41cb9ba6d3dc1fcc115f527a55bd9afa775903324dbd6028f4e78f" \ - "784b03f64a29948a88beffdb035e0b09a7370ccf0cd9ce6bcf8e640c2107318fab87bd9afa775903" \ - "324dbd6028f4e78f784b05d87e15713454616f5b0ed7849ab5c1712ab84f02349478ec2a38f970c0" \ - "1489bd9afa775903324dbd6028f4e78f784b06eb5badd26e4fae65f9a42358deef7c18e52cc05fbb" \ - "7fc76776e69d1b982a14bd9afa775903324dbd6028f4e78f784b08bb2289e9e91b4d20ff3f156251" \ - "6ab07e979b2c6cefe2ab70c6dfc1199f8da5bd9afa775903324dbd6028f4e78f784b0928f0408bf7" \ - "25e61d67d87138a8eebc52962d2847f16e3587163b160e41b6adbd9afa775903324dbd6028f4e78f" \ - "784b09f98aa90f85198c0d73f89ba77e87ec6f596c491350fb8f8bba80a62fbb914bbd9afa775903" \ - "324dbd6028f4e78f784b0a75ea0b1d70eaa4d3f374246db54fc7b43e7f596a353309b9c36b4fd975" \ - "725ebd9afa775903324dbd6028f4e78f784b0c51d7906fc4931149765da88682426b2cfe9e6aa4f2" \ - "7253eab400111432e3a7bd9afa775903324dbd6028f4e78f784b0fa3a29ad05130d7fe5bf4d25965" \ - "63cded1d874096aacc181069932a2e49519abd9afa775903324dbd6028f4e78f784b147730b42f11" \ - "fe493fe902b6251e97cd2b6f34d36af59330f11d02a42f940d07bd9afa775903324dbd6028f4e78f" \ - "784b148fe18f715a9fcfe1a444ce0fff7f85869eb422330dc04b314c0f295d6da79ebd9afa775903" \ - "324dbd6028f4e78f784b1b909115a8d473e51328a87823bd621ce655dfae54fa2bfa72fdc0298611" \ - "d6b8bd9afa775903324dbd6028f4e78f784b1d8b58c1fdb8da8b33ccee1e5f973af734d90ef317e3" \ - "3f5db1573c2ba088a80cbd9afa775903324dbd6028f4e78f784b1f179186efdf5ef2de018245ba0e" \ - "ae8134868601ba0d35ff3d9865c1537ced93bd9afa775903324dbd6028f4e78f784b270c84b29d86" \ - "f16312b06aaae4ebb8dff8de7d080d825b8839ff1766274eff47bd9afa775903324dbd6028f4e78f" \ - "784b29cca4544ea330d61591c784695c149c6b040022ac7b5b89cbd72800d10840eabd9afa775903" \ - "324dbd6028f4e78f784b2b2298eaa26b9dc4a4558ae92e7bb0e4f85cf34bf848fdf636c0c11fbec4" \ - "9897bd9afa775903324dbd6028f4e78f784b2dcf8e8d817023d1e8e1451a3d68d6ec30d9bed94cbc" \ - "b87f19ddc1cc0116ac1abd9afa775903324dbd6028f4e78f784b311a2ac55b50c09b30b3cc93b994" \ - "a119153eeeac54ef892fc447bbbd96101aa1bd9afa775903324dbd6028f4e78f784b32ad3296829b" \ - "c46dcfac5eddcb9dbf2c1eed5c11f83b2210cf9c6e60c798d4a7bd9afa775903324dbd6028f4e78f" \ - "784b340da32b58331c8e2b561baf300ca9dfd6b91cd2270ee0e2a34958b1c6259e85bd9afa775903" \ - "324dbd6028f4e78f784b362ed31d20b1e00392281231a96f0a0acfde02618953e695c9ef2eb0bac3" \ - "7550bd9afa775903324dbd6028f4e78f784b367a31e5838831ad2c074647886a6cdff217e6b1ba91" \ - "0bff85dc7a87ae9b5e98bd9afa775903324dbd6028f4e78f784b3765d769c05bf98b427b3511903b" \ - "2137e8a49b6f859d0af159ed6a86786aa634bd9afa775903324dbd6028f4e78f784b386d695cdf2d" \ - "4576e01bcaccf5e49e78da51af9955c0b8fa7606373b007994b3bd9afa775903324dbd6028f4e78f" \ - "784b3a4f74beafae2b9383ad8215d233a6cf3d057fb3c7e213e897beef4255faee9dbd9afa775903" \ - "324dbd6028f4e78f784b3ae76c45ca70e9180c1559981f42622dd251bca1fbe6b901c52ec11673b0" \ - "3514bd9afa775903324dbd6028f4e78f784b3be8e7eb348d35c1928f19c769846788991641d1f6cf" \ - "09514ca10269934f7359bd9afa775903324dbd6028f4e78f784b3e3926f0b8a15ad5a14167bb647a" \ - "843c3d4321e35dbc44dce8c837417f2d28b0bd9afa775903324dbd6028f4e78f784b400ac66d59b7" \ - "b094a9e30b01a6bd013aff1d30570f83e7592f421dbe5ff4ba8fbd9afa775903324dbd6028f4e78f" \ - "784b4185821f6dab5ba8347b78a22b5f9a0a7570ca5c93a74d478a793d83bac49805bd9afa775903" \ - "324dbd6028f4e78f784b41d1eeb177c0324e17dd6557f384e532de0cf51a019a446b01efb351bc25" \ - "9d77bd9afa775903324dbd6028f4e78f784b45876b4dd861d45b3a94800774027a5db45a48b2a729" \ - "410908b6412f8a87e95dbd9afa775903324dbd6028f4e78f784b4667bf250cd7c1a06b8474c613cd" \ - "b1df648a7f58736fbf57d05d6f755dab67f4bd9afa775903324dbd6028f4e78f784b47ff1b63b140" \ - "b6fc04ed79131331e651da5b2e2f170f5daef4153dc2fbc532b1bd9afa775903324dbd6028f4e78f" \ - "784b57e6913afacc5222bd76cdaf31f8ed88895464255374ef097a82d7f59ad39596bd9afa775903" \ - "324dbd6028f4e78f784b5890fa227121c76d90ed9e63c87e3a6533eea0f6f0a1a23f1fc445139bc6" \ - "bcdfbd9afa775903324dbd6028f4e78f784b5d1e9acbbb4a7d024b6852df025970e2ced66ff622ee" \ - "019cd0ed7fd841ccad02bd9afa775903324dbd6028f4e78f784b61cec4a377bf5902c0feaee37034" \ - "bf97d5bc6e0615e23a1cdfbae6e3f5fb3cfdbd9afa775903324dbd6028f4e78f784b631f0857b418" \ - "45362c90c6980b4b10c4b628e23dbe24b6e96c128ae3dcb0d5acbd9afa775903324dbd6028f4e78f" \ - "784b65b2e7cc18d903c331df1152df73ca0dc932d29f17997481c56f3087b2dd3147bd9afa775903" \ - "324dbd6028f4e78f784b66aa13a0edc219384d9c425d3927e6ed4a5d1940c5e7cd4dac88f5770103" \ - "f2f1bd9afa775903324dbd6028f4e78f784b6873d2f61c29bd52e954eeff5977aa8367439997811a" \ - "62ff212c948133c68d97bd9afa775903324dbd6028f4e78f784b6dbbead23e8c860cf8b47f74fbfc" \ - "a5204de3e28b881313bb1d1eccdc4747934ebd9afa775903324dbd6028f4e78f784b6dead13257df" \ - "c3ccc6a4b37016ba91755fe9e0ec1f415030942e5abc47f07c88bd9afa775903324dbd6028f4e78f" \ - "784b70a1450af2ad395569ad0afeb1d9c125324ee90aec39c258880134d4892d51abbd9afa775903" \ - "324dbd6028f4e78f784b72c26f827ceb92989798961bc6ae748d141e05d3ebcfb65d9041b266c920" \ - "be82bd9afa775903324dbd6028f4e78f784b781764102188a8b4b173d4a8f5ec94d828647156097f" \ - "99357a581e624b377509bd9afa775903324dbd6028f4e78f784b788383a4c733bb87d2bf51673dc7" \ - "3e92df15ab7d51dc715627ae77686d8d23bcbd9afa775903324dbd6028f4e78f784b78b4edcaabc8" \ - "d9093e20e217802caeb4f09e23a3394c4acc6e87e8f35395310fbd9afa775903324dbd6028f4e78f" \ - "784b7f49ccb309323b1c7ab11c93c955b8c744f0a2b75c311f495e18906070500027bd9afa775903" \ - "324dbd6028f4e78f784b82acba48d5236ccff7659afc14594dee902bd6082ef1a30a0b9b508628cf" \ - "34f4bd9afa775903324dbd6028f4e78f784b894d7839368f3298cc915ae8742ef330d7a26699f459" \ - "478cf22c2b6bb2850166bd9afa775903324dbd6028f4e78f784b8c0349d708571ae5aa21c1136348" \ - "2332073297d868f29058916529efc520ef70bd9afa775903324dbd6028f4e78f784b8d93d60c6919" \ - "59651476e5dc464be12a85fa5280b6f524d4a1c3fcc9d048cfadbd9afa775903324dbd6028f4e78f" \ - "784b9063f5fbc5e57ab6de6c9488146020e172b176d5ab57d4c89f0f600e17fe2de2bd9afa775903" \ - "324dbd6028f4e78f784b91656aa4ef493b3824a0b7263248e4e2d657a5c8488d880cb65b01730932" \ - "fb53bd9afa775903324dbd6028f4e78f784b91971c1497bf8e5bc68439acc48d63ebb8faabfd764d" \ - "cbe82f3ba977cac8cf6abd9afa775903324dbd6028f4e78f784b947078f97c6196968c3ae99c9a5d" \ - "58667e86882cf6c8c9d58967a496bb7af43cbd9afa775903324dbd6028f4e78f784b96e4509450d3" \ - "80dac362ff8e295589128a1f1ce55885d20d89c27ba2a9d00909bd9afa775903324dbd6028f4e78f" \ - "784b9783b5ee4492e9e891c655f1f48035959dad453c0e623af0fe7bf2c0a57885e3bd9afa775903" \ - "324dbd6028f4e78f784b97a51a094444620df38cd8c6512cac909a75fd437ae1e4d2292980766123" \ - "8127bd9afa775903324dbd6028f4e78f784b97a8c5ba11d61fefbb5d6a05da4e15ba472dc4c6cd49" \ - "72fc1a035de321342fe4bd9afa775903324dbd6028f4e78f784b992820e6ec8c41daae4bd8ab48f5" \ - "8268e943a670d35ca5e2bdcd3e7c4c94a072bd9afa775903324dbd6028f4e78f784b9954a1a99d55" \ - "e8b189ab1bca414b91f6a017191f6c40a86b6f3ef368dd860031bd9afa775903324dbd6028f4e78f" \ - "784b9baf4f76d76bf5d6a897bfbd5f429ba14d04e08b48c3ee8d76930a828fff3891bd9afa775903" \ - "324dbd6028f4e78f784b9c259fcb301d5fc7397ed5759963e0ef6b36e42057fd73046e6bd08b149f" \ - "751cbd9afa775903324dbd6028f4e78f784b9dd2dcb72f5e741627f2e9e03ab18503a3403cf6a904" \ - "a479a4db05d97e2250a9bd9afa775903324dbd6028f4e78f784b9ed33f0fbc180bc032f8909ca2c4" \ - "ab3418edc33a45a50d2521a3b5876aa3ea2cbd9afa775903324dbd6028f4e78f784ba4d978b7c4bd" \ - "a15435d508f8b9592ec2a5adfb12ea7bad146a35ecb53094642fbd9afa775903324dbd6028f4e78f" \ - "784ba924d3cad6da42b7399b96a095a06f18f6b1aba5b873b0d5f3a0ee2173b48b6cbd9afa775903" \ - "324dbd6028f4e78f784bad3be589c0474e97de5bb2bf33534948b76bb80376dfdc58b1fed767b5a1" \ - "5bfcbd9afa775903324dbd6028f4e78f784bb8d6b5e7857b45830e017c7be3d856adeb97c7290eb0" \ - "665a3d473a4beb51dcf3bd9afa775903324dbd6028f4e78f784bb93f0699598f8b20fa0dacc12cfc" \ - "fc1f2568793f6e779e04795e6d7c22530f75bd9afa775903324dbd6028f4e78f784bbb01da0333bb" \ - "639c7e1c806db0561dc98a5316f22fef1090fb8d0be46dae499abd9afa775903324dbd6028f4e78f" \ - "784bbc75f910ff320f5cb5999e66bbd4034f4ae537a42fdfef35161c5348e366e216bd9afa775903" \ - "324dbd6028f4e78f784bbdd01126e9d85710d3fe75af1cc1702a29f081b4f6fdf6a2b2135c0297a9" \ - "cec5bd9afa775903324dbd6028f4e78f784bbe435df7cd28aa2a7c8db4fc8173475b77e5abf392f7" \ - "6b7c76fa3f698cb71a9abd9afa775903324dbd6028f4e78f784bbef7663be5ea4dbfd8686e24701e" \ - "036f4c03fb7fcd67a6c566ed94ce09c44470bd9afa775903324dbd6028f4e78f784bc2469759c194" \ - "7e14f4b65f72a9f5b3af8b6f6e727b68bb0d91385cbf42176a8abd9afa775903324dbd6028f4e78f" \ - "784bc3505bf3ec10a51dace417c76b8bd10939a065d1f34e75b8a3065ee31cc69b96bd9afa775903" \ - "324dbd6028f4e78f784bc42d11c70ccf5e8cf3fb91fdf21d884021ad836ca68adf2cbb7995c10bf5" \ - "88d4bd9afa775903324dbd6028f4e78f784bc69d64a5b839e41ba16742527e17056a18ce3c276fd2" \ - "6e34901a1bc7d0e32219bd9afa775903324dbd6028f4e78f784bcb340011afeb0d74c4a588b36eba" \ - "a441961608e8d2fa80dca8c13872c850796bbd9afa775903324dbd6028f4e78f784bcc8eec6eb921" \ - "2cbf897a5ace7e8abeece1079f1a6def0a789591cb1547f1f084bd9afa775903324dbd6028f4e78f" \ - "784bcf13a243c1cd2e3c8ceb7e70100387cecbfb830525bbf9d0b70c79adf3e84128bd9afa775903" \ - "324dbd6028f4e78f784bd89a11d16c488dd4fbbc541d4b07faf8670d660994488fe54b1fbff2704e" \ - "4288bd9afa775903324dbd6028f4e78f784bd9668ab52785086786c134b5e4bddbf72452813b6973" \ - "229ab92aa1a54d201bf5bd9afa775903324dbd6028f4e78f784bda3560fd0c32b54c83d4f2ff8690" \ - "03d2089369acf2c89608f8afa7436bfa4655bd9afa775903324dbd6028f4e78f784bdf02aab48387" \ - "a9e1d4c65228089cb6abe196c8f4b396c7e4bbc395de136977f6bd9afa775903324dbd6028f4e78f" \ - "784bdf91ac85a94fcd0cfb8155bd7cbefaac14b8c5ee7397fe2cc85984459e2ea14ebd9afa775903" \ - "324dbd6028f4e78f784be051b788ecbaeda53046c70e6af6058f95222c046157b8c4c1b9c2cfc65f" \ - "46e5bd9afa775903324dbd6028f4e78f784be36dfc719d2114c2e39aea88849e2845ab326f6f7fe7" \ - "4e0e539b7e54d81f3631bd9afa775903324dbd6028f4e78f784be39891f48bbcc593b8ed86ce82ce" \ - "666fc1145b9fcbfd2b07bad0a89bf4c7bfbfbd9afa775903324dbd6028f4e78f784be6856f137f79" \ - "992dc94fa2f43297ec32d2d9a76f7be66114c6a13efc3bcdf5c8bd9afa775903324dbd6028f4e78f" \ - "784beaff8c85c208ba4d5b6b8046f5d6081747d779bada7768e649d047ff9b1f660cbd9afa775903" \ - "324dbd6028f4e78f784bee83a566496109a74f6ac6e410df00bb29a290e0021516ae3b8a23288e7e" \ - "2e72bd9afa775903324dbd6028f4e78f784beed7e0eff2ed559e2a79ee361f9962af3b1e999131e3" \ - "0bb7fd07546fae0a7267bd9afa775903324dbd6028f4e78f784bf1b4f6513b0d544a688d13adc291" \ - "efa8c59f420ca5dcb23e0b5a06fa7e0d083dbd9afa775903324dbd6028f4e78f784bf2a16d35b554" \ - "694187a70d40ca682959f4f35c2ce0eab8fd64f7ac2ab9f5c24abd9afa775903324dbd6028f4e78f" \ - "784bf31fd461c5e99510403fc97c1da2d8a9cbe270597d32badf8fd66b77495f8d94bd9afa775903" \ - "324dbd6028f4e78f784bf48e6dd8718e953b60a24f2cbea60a9521deae67db25425b7d3ace3c517d" \ - "d9b7bd9afa775903324dbd6028f4e78f784bc805603c4fa038776e42f263c604b49d96840322e192" \ - "2d5606a9b0bbb5bffe6fbd9afa775903324dbd6028f4e78f784b1f16078cce009df62edb9e7170e6" \ - "6caae670bce71b8f92d38280c56aa372031dbd9afa775903324dbd6028f4e78f784b37a480374daf" \ - "6202ce790c318a2bb8aa3797311261160a8e30558b7dea78c7a6bd9afa775903324dbd6028f4e78f" \ - "784b408b8b3df5abb043521a493525023175ab1261b1de21064d6bf247ce142153b9bd9afa775903" \ - "324dbd6028f4e78f784b540801dd345dc1c33ef431b35bf4c0e68bd319b577b9abe1a9cff1cbc39f" \ - "548fbd9afa775903324dbd6028f4e78f784b040b3bc339e9b6f9acd828b88f3482a5c3f64e67e5a7" \ - "14ba1da8a70453b34af6bd9afa775903324dbd6028f4e78f784b1142a0cc7c9004dff64c5948484d" \ - "6a7ec3514e176f5ca6bdeed7a093940b93ccbd9afa775903324dbd6028f4e78f784b288878f12e8b" \ - "9c6ccbf601c73d5f4e985cac0ff3fcb0c24e4414912b3eb91f15bd9afa775903324dbd6028f4e78f" \ - "784b2ea4cb6a1f1eb1d3dce82d54fde26ded243ba3e18de7c6d211902a594fe56788bd9afa775903" \ - "324dbd6028f4e78f784b40d6cae02973789080cf4c3a9ad11b5a0a4d8bba4438ab96e276cc784454" \ - "dee7bd9afa775903324dbd6028f4e78f784b4f0214fce4fa8897d0c80a46d6dab4124726d136fc24" \ - "92efd01bfedfa3887a9cbd9afa775903324dbd6028f4e78f784b5c2afe34bd8a7aebbb439c251dfb" \ - "6a424f00e535ac4df61ec19745b6f10e893abd9afa775903324dbd6028f4e78f784b99d7ada0d67e" \ - "5233108dbd76702f4b168087cfc4ec65494d6ca8aba858febadabd9afa775903324dbd6028f4e78f" \ - "784ba608a87f51bdf7532b4b80fa95eadfdf1bf8b0cbb58a7d3939c9f11c12e71c85bd9afa775903" \ - "324dbd6028f4e78f784bbdd4086c019f5d388453c6d93475d39a576572baff75612c321b46a35a53" \ - "29b1bd9afa775903324dbd6028f4e78f784bcb994b400590b66cbf55fc663555caf0d4f1ce267464" \ - "d0452c2361e05ee1cd50bd9afa775903324dbd6028f4e78f784bd6ee8db782e36caffb4d9f820790" \ - "0487de930aabcc1d196fa455fbfd6f37273dbd9afa775903324dbd6028f4e78f784bdda0121dcf16" \ - "7db1e2622d10f454701837ac6af304a03ec06b3027904988c56bbd9afa775903324dbd6028f4e78f" \ - "784be42572afac720f5d4a1c7aaaf802f094daceb682f4e92783b2bb3fa00862af7fbd9afa775903" \ - "324dbd6028f4e78f784be6236dc1ee074c077c7a1c9b3965947430847be125f7aeb71d91a128133a" \ - "ea7fbd9afa775903324dbd6028f4e78f784bef87be89a413657de8721498552cf9e0f3c1f71bc62d" \ - "fa63b9f25bbc66e86494bd9afa775903324dbd6028f4e78f784bf5e892dd6ec4c2defa4a495c0921" \ - "9b621379b64da3d1b2e34adf4b5f1102bd39bd9afa775903324dbd6028f4e78f784bd4241190cd5a" \ - "369d8c344c660e24f3027fb8e7064fab33770e93fa765ffb152ebd9afa775903324dbd6028f4e78f" \ - "784b23142e14424fb3ff4efc75d00b63867727841aba5005149070ee2417df8ab799bd9afa775903" \ - "324dbd6028f4e78f784b91721aa76266b5bb2f8009f1188510a36e54afd56e967387ea7d0b114d78" \ - "2089bd9afa775903324dbd6028f4e78f784bdc8aff7faa9d1a00a3e32eefbf899b3059cbb313a48b" \ - "82fa9c8d931fd58fb69dbd9afa775903324dbd6028f4e78f784b9959ed4e05e548b59f219308a455" \ - "63ea85bb224c1ad96dec0e96c0e71ffccd81bd9afa775903324dbd6028f4e78f784b47b31a1c7867" \ - "644b2ee8093b2d5fbe21e21f77c1617a2c08812f57ace0850e9fbd9afa775903324dbd6028f4e78f" \ - "784bfabc379df395e6f52472b44fa5082f9f0e0da480f05198c66814b7055b03f446bd9afa775903" \ - "324dbd6028f4e78f784be37ff3fc0eff20bfc1c060a4bf56885e1efd55a8e9ce3c5f4869444cacff" \ - "ad0bbd9afa775903324dbd6028f4e78f784b4cdae3920a512c9c052a8b4aba9096969b0a0197b614" \ - "031e4c64a5d898cb09b9bd9afa775903324dbd6028f4e78f784b5b89f1aa2435a03d18d9b203d17f" \ - "b4fba4f8f5076cf1f9b8d6d9b826222235c1bd9afa775903324dbd6028f4e78f784b007f4c951257" \ - "13b112093e21663e2d23e3c1ae9ce4b5de0d58a297332336a2d8bd9afa775903324dbd6028f4e78f" \ - "784be060da09561ae00dcfb1769d6e8e846868a1e99a54b14aa5d0689f2840cec6dfbd9afa775903" \ - "324dbd6028f4e78f784b48f4584de1c5ec650c25e6c623635ce101bd82617fc400d4150f0aee2355" \ - "b4cabd9afa775903324dbd6028f4e78f784baf79b14064601bc0987d4747af1e914a228c05d622ce" \ - "da03b7a4f67014fee767bd9afa775903324dbd6028f4e78f784bc3d65e174d47d3772cb431ea599b" \ - "ba76b8670bfaa51081895796432e2ef6461fbd9afa775903324dbd6028f4e78f784b1e918f170a79" \ - "6b4b0b1400bb9bdae75be1cf86705c2d0fc8fb9dd0c5016b933bbd9afa775903324dbd6028f4e78f" \ - "784b66d0803e2550d9e790829ae1b5f81547cc9bfbe69b51817068ecb5dabb7a89fcbd9afa775903" \ - "324dbd6028f4e78f784b284153e7d04a9f187e5c3dbfe17b2672ad2fbdd119f27bec789417b79198" \ - "53ecbd9afa775903324dbd6028f4e78f784bedd2cb55726e10abedec9de8ca5ded289ad793ab3b69" \ - "19d163c875fec1209cd5bd9afa775903324dbd6028f4e78f784b90aec5c4995674a849c1d1384463" \ - "f3b02b5aa625a5c320fc4fe7d9bb58a62398" +DBXFILE = ( + "da070306131115000000000000000000f60c00000002f10e9dd2af4adf68ee498aa9347d375665a7" + "30820cda020101310f300d06096086480165030402010500300b06092a864886f70d010701a0820a" + "ed308204fd308203e5a0030201020213330000002596d20c5c53120043000000000025300d06092a" + "864886f70d01010b0500308180310b3009060355040613025553311330110603550408130a576173" + "68696e67746f6e3110300e060355040713075265646d6f6e64311e301c060355040a13154d696372" + "6f736f667420436f72706f726174696f6e312a3028060355040313214d6963726f736f667420436f" + "72706f726174696f6e204b454b2043412032303131301e170d3231303930323138323433315a170d" + "3232303930313138323433315a308186310b3009060355040613025553311330110603550408130a" + "57617368696e67746f6e3110300e060355040713075265646d6f6e64311e301c060355040a13154d" + "6963726f736f667420436f72706f726174696f6e3130302e060355040313274d6963726f736f6674" + "2057696e646f77732055454649204b65792045786368616e6765204b657930820122300d06092a86" + "4886f70d01010105000382010f003082010a0282010100cabe8aef9b0f8692546db68e66e1585f14" + "ebebe6eed227c8fa323674b22e24efbafa169e7a5fa4c2e6f252076ab245a4f8cf358d0d9c618caf" + "ae8ad1807cd50c1923a741a3525a4e32e78d21b83b06351703349de5635e77b2ac3e502fb7231c59" + "e3f3c977139eeb65e44324f6cf04701fd5962995d0f573012769eea20942a7bec1f7e67d4b2e6ed8" + "a958a98e4043aa6f620b676becebab447f6ecbf174fda343ba10cbfc1e05c2d652d3a139626f4a18" + "e7f8bf3fa412f63fc13af332040049d2b26ea270c5cf914f56661de0d54ce3bc3399e01e016190a0" + "3dc8826a87b032e01526dadd767ef07c0ba72953d021115f87264bf21c6cb8dbe6c7f067087cb702" + "03010001a38201663082016230140603551d25040d300b06092b0601040182374f01301d0603551d" + "0e04160414753d9cab3265b73cafcc22f9b16ba1e38dcf8d6130450603551d11043e303ca43a3038" + "311e301c060355040b13154d6963726f736f667420436f72706f726174696f6e3116301406035504" + "05130d3232393936312b343637353933301f0603551d2304183016801462fc43cda03ea4cb6712d2" + "5bd955ac7bccb68a5f30530603551d1f044c304a3048a046a0448642687474703a2f2f7777772e6d" + "6963726f736f66742e636f6d2f706b696f70732f63726c2f4d6963436f724b454b4341323031315f" + "323031312d30362d32342e63726c306006082b0601050507010104543052305006082b0601050507" + "30028644687474703a2f2f7777772e6d6963726f736f66742e636f6d2f706b696f70732f63657274" + "732f4d6963436f724b454b4341323031315f323031312d30362d32342e637274300c0603551d1301" + "01ff04023000300d06092a864886f70d01010b0500038201010069662ba664b30e7f47e3308e9cbf" + "0f6c1250bd8eecd227c8a223c5ced041a35bef9d8aa41a31ceee757163a15d4fdc921518daa17087" + "3922e85324a6d2a7c2a74b483a488f7ef0262324568d63914a9d66915ee9f6a4c1c0f07592689c16" + "833a87006ce0f650b15314b0f4f3bb0b3d623db77a4d526e8dc1d9358f2a3a6a76661a41677f4d00" + "a2979e8493e27106e3b5414d11dc91d0c0dbe83ea3b188959b48889350293669c8bf9315b34d2aae" + "0f64b78e36051c341cde7d77ec06aa47c6aa35f0bf6f36455fbc17c431b6048bc2003c88b48f04b3" + "52da0fbef900a2f20262d867a54d4dd841605e1d4b0024d46f6c79cd4fd5b3c022107ac921ed71e0" + "8a59308205e8308203d0a003020102020a610ad188000000000003300d06092a864886f70d01010b" + "0500308191310b3009060355040613025553311330110603550408130a57617368696e67746f6e31" + "10300e060355040713075265646d6f6e64311e301c060355040a13154d6963726f736f667420436f" + "72706f726174696f6e313b3039060355040313324d6963726f736f667420436f72706f726174696f" + "6e205468697264205061727479204d61726b6574706c61636520526f6f74301e170d313130363234" + "3230343132395a170d3236303632343230353132395a308180310b30090603550406130255533113" + "30110603550408130a57617368696e67746f6e3110300e060355040713075265646d6f6e64311e30" + "1c060355040a13154d6963726f736f667420436f72706f726174696f6e312a302806035504031321" + "4d6963726f736f667420436f72706f726174696f6e204b454b204341203230313130820122300d06" + "092a864886f70d01010105000382010f003082010a0282010100c4e8b58abfad5726b026c3eae7fb" + "577a44025d070dda4ae5742ae6b00fec6debec7fb9e35a63327c11174f0ee30ba73815938ec6f5e0" + "84b19a9b2ce7f5b791d609e1e2c004a8ac301cdf48f306509a64a7517fc8854f8f2086cefe2fe19f" + "ff82c0ede9cdcef4536a623a0b43b9e225fdfe05f9d4c414ab11e223898d70b7a41d4decaee59cfa" + "16c2d7c1cbd4e8c42fe599ee248b03ec8df28beac34afb4311120b7eb547926cdce60489ebf53304" + "eb10012a71e5f983133cff25092f687646ffba4fbedcad712a58aafb0ed2793de49b653bcc292a9f" + "fc7259a2ebae92eff6351380c602ece45fcc9d76cdef6392c1af79408479877fe352a8e89d7b0769" + "8f150203010001a382014f3082014b301006092b06010401823715010403020100301d0603551d0e" + "0416041462fc43cda03ea4cb6712d25bd955ac7bccb68a5f301906092b0601040182371402040c1e" + "0a00530075006200430041300b0603551d0f040403020186300f0603551d130101ff040530030101" + "ff301f0603551d2304183016801445665243e17e5811bfd64e9e2355083b3a226aa8305c0603551d" + "1f045530533051a04fa04d864b687474703a2f2f63726c2e6d6963726f736f66742e636f6d2f706b" + "692f63726c2f70726f64756374732f4d6963436f725468695061724d6172526f6f5f323031302d31" + "302d30352e63726c306006082b0601050507010104543052305006082b0601050507300286446874" + "74703a2f2f7777772e6d6963726f736f66742e636f6d2f706b692f63657274732f4d6963436f7254" + "68695061724d6172526f6f5f323031302d31302d30352e637274300d06092a864886f70d01010b05" + "000382020100d48488f514941802ca2a3cfb2a921c0cd7a0d1f1e85266a8eea2b5757a9000aa2da4" + "765aea79b7b9376a517b1064f6e164f20267bef7a81b78bdbace8858640cd657c819a35f05d6dbc6" + "d069ce484b32b7eb5dd230f5c0f5b8ba7807a32bfe9bdb345684ec82caae4125709c6be9fe900fd7" + "961fe5e7941fb22a0c8d4bff2829107bf7d77ca5d176b905c879ed0f90929cc2fedf6f7e6c0f7bd4" + "c145dd345196390fe55e56d8180596f407a642b3a077fd0819f27156cc9f8623a487cba6fd587ed4" + "696715917e81f27f13e50d8b8a3c8784ebe3cebd43e5ad2d84938e6a2b5a7c44fa52aa81c82d1cbb" + "e052df0011f89a3dc160b0e133b5a388d165190a1ae7ac7ca4c182874e38b12f0dc514876ffd8d2e" + "bc39b6e7e6c3e0e4cd2784ef9442ef298b9046413b811b67d8f9435965cb0dbcfd00924ff4753ba7" + "a924fc50414079e02d4f0a6a27766e52ed96697baf0ff78705d045c2ad5314811ffb3004aa373661" + "da4a691b34d868edd602cf6c940cd3cf6c2279adb1f0bc03a24660a9c407c22182f1fdf2e8793260" + "bfd8aca522144bcac1d84beb7d3f5735b2e64f75b4b060032253ae91791dd69b411f15865470b2de" + "0d350f7cb03472ba97603bf079eba2b21c5da216b887c5e91bf6b597256f389fe391fa8a7998c369" + "0eb7a31c200597f8ca14ae00d7c4f3c01410756b34a01bb59960f35cb0c5574e36d23284bf9e3182" + "01c4308201c0020101308198308180310b3009060355040613025553311330110603550408130a57" + "617368696e67746f6e3110300e060355040713075265646d6f6e64311e301c060355040a13154d69" + "63726f736f667420436f72706f726174696f6e312a3028060355040313214d6963726f736f667420" + "436f72706f726174696f6e204b454b20434120323031310213330000002596d20c5c531200430000" + "00000025300d06096086480165030402010500300d06092a864886f70d01010105000482010002fc" + "f6d3fb1c3e7af2bff3a028b0d2ddace519e9d3bf9eaccc0b89e69ba782e42a6b7b723cbca7f93130" + "b79053db51f5c9e30b0607cb6144170a1e2053ba1edd1553c44cf694c094e594e904d341d157789a" + "cebbf327b52a9027113195403625a47137dc8d779414d3cf434d0077d61de393a960f1525bbb8c90" + "b6db9ffa1763bffc50e9f89a33c8a58fc3af6a6174d18ee42b60b32ed0edf014124e0cb65943b573" + "b72b9c36b837b686f1026874428c6b61cb6fec305fd51dde53b32ead7575d8a9b8de4079d6476b16" + "db7d1b029ad59f76a1ed7b532d05e50870eb873cd86c843b19a9e2ae412ad0f1c768802626098dc8" + "e1513529e6c7e062801e1ee7daa02616c4c14c509240aca941f936934328cc280000000000003000" + "0000bd9afa775903324dbd6028f4e78f784b80b4d96931bf0d02fd91a61e19d14f1da452e66db240" + "8ca8604d411f92659f0abd9afa775903324dbd6028f4e78f784bf52f83a3fa9cfbd6920f722824db" + "e4034534d25b8507246b3b957dac6e1bce7abd9afa775903324dbd6028f4e78f784bc5d9d8a186e2" + "c82d09afaa2a6f7f2e73870d3e64f72c4e08ef67796a840f0fbdbd9afa775903324dbd6028f4e78f" + "784b1aec84b84b6c65a51220a9be7181965230210d62d6d33c48999c6b295a2b0a06bd9afa775903" + "324dbd6028f4e78f784bc3a99a460da464a057c3586d83cef5f4ae08b7103979ed8932742df0ed53" + "0c66bd9afa775903324dbd6028f4e78f784b58fb941aef95a25943b3fb5f2510a0df3fe44c58c95e" + "0ab80487297568ab9771bd9afa775903324dbd6028f4e78f784b5391c3a2fb112102a6aa1edc25ae" + "77e19f5d6f09cd09eeb2509922bfcd5992eabd9afa775903324dbd6028f4e78f784bd626157e1d6a" + "718bc124ab8da27cbb65072ca03a7b6b257dbdcbbd60f65ef3d1bd9afa775903324dbd6028f4e78f" + "784bd063ec28f67eba53f1642dbf7dff33c6a32add869f6013fe162e2c32f1cbe56dbd9afa775903" + "324dbd6028f4e78f784b29c6eb52b43c3aa18b2cd8ed6ea8607cef3cfae1bafe1165755cf2e61484" + "4a44bd9afa775903324dbd6028f4e78f784b90fbe70e69d633408d3e170c6832dbb2d209e0272527" + "dfb63d49d29572a6f44cbd9afa775903324dbd6028f4e78f784b106faceacfecfd4e303b74f480a0" + "8098e2d0802b936f8ec774ce21f31686689cbd9afa775903324dbd6028f4e78f784b174e3a0b5b43" + "c6a607bbd3404f05341e3dcf396267ce94f8b50e2e23a9da920cbd9afa775903324dbd6028f4e78f" + "784b2b99cf26422e92fe365fbf4bc30d27086c9ee14b7a6fff44fb2f6b9001699939bd9afa775903" + "324dbd6028f4e78f784b2e70916786a6f773511fa7181fab0f1d70b557c6322ea923b2a8d3b92b51" + "af7dbd9afa775903324dbd6028f4e78f784b3fce9b9fdf3ef09d5452b0f95ee481c2b7f06d743a73" + "7971558e70136ace3e73bd9afa775903324dbd6028f4e78f784b47cc086127e2069a86e03a6bef2c" + "d410f8c55a6d6bdb362168c31b2ce32a5adfbd9afa775903324dbd6028f4e78f784b71f2906fd222" + "497e54a34662ab2497fcc81020770ff51368e9e3d9bfcbfd6375bd9afa775903324dbd6028f4e78f" + "784b82db3bceb4f60843ce9d97c3d187cd9b5941cd3de8100e586f2bda5637575f67bd9afa775903" + "324dbd6028f4e78f784b8ad64859f195b5f58dafaa940b6a6167acd67a886e8f469364177221c559" + "45b9bd9afa775903324dbd6028f4e78f784b8d8ea289cfe70a1c07ab7365cb28ee51edd33cf2506d" + "e888fbadd60ebf80481cbd9afa775903324dbd6028f4e78f784baeebae3151271273ed95aa2e6711" + "39ed31a98567303a332298f83709a9d55aa1bd9afa775903324dbd6028f4e78f784bc409bdac4775" + "add8db92aa22b5b718fb8c94a1462c1fe9a416b95d8a3388c2fcbd9afa775903324dbd6028f4e78f" + "784bc617c1a8b1ee2a811c28b5a81b4c83d7c98b5b0c27281d610207ebe692c2967fbd9afa775903" + "324dbd6028f4e78f784bc90f336617b8e7f983975413c997f10b73eb267fd8a10cb9e3bdbfc667ab" + "db8bbd9afa775903324dbd6028f4e78f784b64575bd912789a2e14ad56f6341f52af6bf80cf94400" + "785975e9f04e2d64d745bd9afa775903324dbd6028f4e78f784b45c7c8ae750acfbb48fc37527d64" + "12dd644daed8913ccd8a24c94d856967df8ebd9afa775903324dbd6028f4e78f784b81d8fb4c9e2e" + "7a8225656b4b8273b7cba4b03ef2e9eb20e0a0291624eca1ba86bd9afa775903324dbd6028f4e78f" + "784bb92af298dc08049b78c77492d6551b710cd72aada3d77be54609e43278ef6e4dbd9afa775903" + "324dbd6028f4e78f784be19dae83c02e6f281358d4ebd11d7723b4f5ea0e357907d5443decc5f93c" + "1e9dbd9afa775903324dbd6028f4e78f784b39dbc2288ef44b5f95332cb777e31103e840dba68063" + "4aa806f5c9b100061802bd9afa775903324dbd6028f4e78f784b32f5940ca29dd812a2c145e6fc89" + "646628ffcc7c7a42cae512337d8d29c40bbdbd9afa775903324dbd6028f4e78f784b10d45fcba396" + "aef3153ee8f6ecae58afe8476a280a2026fc71f6217dcf49ba2fbd9afa775903324dbd6028f4e78f" + "784b4b8668a5d465bcdd9000aa8dfcff42044fcbd0aece32fc7011a83e9160e89f09bd9afa775903" + "324dbd6028f4e78f784b89f3d1f6e485c334cd059d0995e3cdfdc00571b1849854847a44dc5548e2" + "dcfbbd9afa775903324dbd6028f4e78f784bc9ec350406f26e559affb4030de2ebde5435054c35a9" + "98605b8fcf04972d8d55bd9afa775903324dbd6028f4e78f784bb3e506340fbf6b5786973393079f" + "24b66ba46507e35e911db0362a2acde97049bd9afa775903324dbd6028f4e78f784b9f1863ed5717" + "c394b42ef10a6607b144a65ba11fb6579df94b8eb2f0c4cd60c1bd9afa775903324dbd6028f4e78f" + "784bdd59af56084406e38c63fbe0850f30a0cd1277462a2192590fb05bc259e61273bd9afa775903" + "324dbd6028f4e78f784bdbaf9e056d3d5b38b68553304abc88827ebc00f80cb9c7e197cdbc5822cd" + "316cbd9afa775903324dbd6028f4e78f784b65f3c0a01b8402d362b9722e98f75e5e991e6c186e93" + "4f7b2b2e6be6dec800ecbd9afa775903324dbd6028f4e78f784b5b248e913d71853d3da5aedd8d9a" + "4bc57a917126573817fb5fcb2d86a2f1c886bd9afa775903324dbd6028f4e78f784b2679650fe341" + "f2cf1ea883460b3556aaaf77a70d6b8dc484c9301d1b746cf7b5bd9afa775903324dbd6028f4e78f" + "784bbb1dd16d530008636f232303a7a86f3dff969f848815c0574b12c2d787fec93fbd9afa775903" + "324dbd6028f4e78f784b0ce02100f67c7ef85f4eed368f02bf7092380a3c23ca91fd7f19430d94b0" + "0c19bd9afa775903324dbd6028f4e78f784b95049f0e4137c790b0d2767195e56f73807d123adcf8" + "f6e7bf2d4d991d305f89bd9afa775903324dbd6028f4e78f784b02e6216acaef6401401fa555ecbe" + "d940b1a5f2569aed92956137ae58482ef1b7bd9afa775903324dbd6028f4e78f784b6efefe0b5b01" + "478b7b944c10d3a8aca2cca4208888e2059f8a06cb5824d7bab0bd9afa775903324dbd6028f4e78f" + "784b9d00ae4cd47a41c783dc48f342c076c2c16f3413f4d2df50d181ca3bb5ad859dbd9afa775903" + "324dbd6028f4e78f784bd8d4e6ddf6e42d74a6a536ea62fd1217e4290b145c9e5c3695a31b42efb5" + "f5a4bd9afa775903324dbd6028f4e78f784bf277af4f9bdc918ae89fa35cc1b34e34984c04ae9765" + "322c3cb049574d36509cbd9afa775903324dbd6028f4e78f784b0dc24c75eb1aef56b9f13ab9de60" + "e2eca1c4510034e290bbb36cf60a549b234cbd9afa775903324dbd6028f4e78f784b835881f2a557" + "2d7059b5c8635018552892e945626f115fc9ca07acf7bde857a4bd9afa775903324dbd6028f4e78f" + "784bbadff5e4f0fea711701ca8fb22e4c43821e31e210cf52d1d4f74dd50f1d039bcbd9afa775903" + "324dbd6028f4e78f784bc452ab846073df5ace25cca64d6b7a09d906308a1a65eb5240e3c4ebcaa9" + "cc0cbd9afa775903324dbd6028f4e78f784bf1863ec8b7f43f94ad14fb0b8b4a69497a8c65ecbc2a" + "55e0bb420e772b8cdc91bd9afa775903324dbd6028f4e78f784b7bc9cb5463ce0f011fb5085eb8ba" + "77d1acd283c43f4a57603cc113f22cebc579bd9afa775903324dbd6028f4e78f784be800395dbe0e" + "045781e8005178b4baf5a257f06e159121a67c595f6ae22506fdbd9afa775903324dbd6028f4e78f" + "784b1cb4dccaf2c812cfa7b4938e1371fe2b96910fe407216fd95428672d6c7e7316bd9afa775903" + "324dbd6028f4e78f784b3ece27cbb3ec4438cce523b927c4f05fdc5c593a3766db984c5e437a3ff6" + "a16bbd9afa775903324dbd6028f4e78f784b68ee4632c7be1c66c83e89dd93eaee1294159abf45b4" + "c2c72d7dc7499aa2a043bd9afa775903324dbd6028f4e78f784be24b315a551671483d8b9073b32d" + "e11b4de1eb2eab211afd2d9c319ff55e08d0bd9afa775903324dbd6028f4e78f784be7c20b3ab481" + "ec885501eca5293781d84b5a1ac24f88266b5270e7ecb4aa2538bd9afa775903324dbd6028f4e78f" + "784bdccc3ce1c00ee4b0b10487d372a0fa47f5c26f57a359be7b27801e144eacbac4bd9afa775903" + "324dbd6028f4e78f784b0257ff710f2a16e489b37493c07604a7cda96129d8a8fd68d2b6af633904" + "315dbd9afa775903324dbd6028f4e78f784b3a91f0f9e5287fa2994c7d930b2c1a5ee14ce8e1c830" + "4ae495adc58cc4453c0cbd9afa775903324dbd6028f4e78f784b495300790e6c9bf2510daba59db3" + "d57e9d2b85d7d7640434ec75baa3851c74e5bd9afa775903324dbd6028f4e78f784b81a8b2c9751a" + "eb1faba7dbde5ee9691dc0eaee2a31c38b1491a8146756a6b770bd9afa775903324dbd6028f4e78f" + "784b8e53efdc15f852cee5a6e92931bc42e6163cd30ff649cca7e87252c3a459960bbd9afa775903" + "324dbd6028f4e78f784b992d359aa7a5f789d268b94c11b9485a6b1ce64362b0edb4441ccc187c39" + "647bbd9afa775903324dbd6028f4e78f784b9fa4d5023fd43ecaff4200ba7e8d4353259d2b7e5e72" + "b5096eff8027d66d1043bd9afa775903324dbd6028f4e78f784bd372c0d0f4fdc9f52e9e1f23fc56" + "ee72414a17f350d0cea6c26a35a6c3217a13bd9afa775903324dbd6028f4e78f784b5c5805196a85" + "e93789457017d4f9eb6828b97c41cb9ba6d3dc1fcc115f527a55bd9afa775903324dbd6028f4e78f" + "784b03f64a29948a88beffdb035e0b09a7370ccf0cd9ce6bcf8e640c2107318fab87bd9afa775903" + "324dbd6028f4e78f784b05d87e15713454616f5b0ed7849ab5c1712ab84f02349478ec2a38f970c0" + "1489bd9afa775903324dbd6028f4e78f784b06eb5badd26e4fae65f9a42358deef7c18e52cc05fbb" + "7fc76776e69d1b982a14bd9afa775903324dbd6028f4e78f784b08bb2289e9e91b4d20ff3f156251" + "6ab07e979b2c6cefe2ab70c6dfc1199f8da5bd9afa775903324dbd6028f4e78f784b0928f0408bf7" + "25e61d67d87138a8eebc52962d2847f16e3587163b160e41b6adbd9afa775903324dbd6028f4e78f" + "784b09f98aa90f85198c0d73f89ba77e87ec6f596c491350fb8f8bba80a62fbb914bbd9afa775903" + "324dbd6028f4e78f784b0a75ea0b1d70eaa4d3f374246db54fc7b43e7f596a353309b9c36b4fd975" + "725ebd9afa775903324dbd6028f4e78f784b0c51d7906fc4931149765da88682426b2cfe9e6aa4f2" + "7253eab400111432e3a7bd9afa775903324dbd6028f4e78f784b0fa3a29ad05130d7fe5bf4d25965" + "63cded1d874096aacc181069932a2e49519abd9afa775903324dbd6028f4e78f784b147730b42f11" + "fe493fe902b6251e97cd2b6f34d36af59330f11d02a42f940d07bd9afa775903324dbd6028f4e78f" + "784b148fe18f715a9fcfe1a444ce0fff7f85869eb422330dc04b314c0f295d6da79ebd9afa775903" + "324dbd6028f4e78f784b1b909115a8d473e51328a87823bd621ce655dfae54fa2bfa72fdc0298611" + "d6b8bd9afa775903324dbd6028f4e78f784b1d8b58c1fdb8da8b33ccee1e5f973af734d90ef317e3" + "3f5db1573c2ba088a80cbd9afa775903324dbd6028f4e78f784b1f179186efdf5ef2de018245ba0e" + "ae8134868601ba0d35ff3d9865c1537ced93bd9afa775903324dbd6028f4e78f784b270c84b29d86" + "f16312b06aaae4ebb8dff8de7d080d825b8839ff1766274eff47bd9afa775903324dbd6028f4e78f" + "784b29cca4544ea330d61591c784695c149c6b040022ac7b5b89cbd72800d10840eabd9afa775903" + "324dbd6028f4e78f784b2b2298eaa26b9dc4a4558ae92e7bb0e4f85cf34bf848fdf636c0c11fbec4" + "9897bd9afa775903324dbd6028f4e78f784b2dcf8e8d817023d1e8e1451a3d68d6ec30d9bed94cbc" + "b87f19ddc1cc0116ac1abd9afa775903324dbd6028f4e78f784b311a2ac55b50c09b30b3cc93b994" + "a119153eeeac54ef892fc447bbbd96101aa1bd9afa775903324dbd6028f4e78f784b32ad3296829b" + "c46dcfac5eddcb9dbf2c1eed5c11f83b2210cf9c6e60c798d4a7bd9afa775903324dbd6028f4e78f" + "784b340da32b58331c8e2b561baf300ca9dfd6b91cd2270ee0e2a34958b1c6259e85bd9afa775903" + "324dbd6028f4e78f784b362ed31d20b1e00392281231a96f0a0acfde02618953e695c9ef2eb0bac3" + "7550bd9afa775903324dbd6028f4e78f784b367a31e5838831ad2c074647886a6cdff217e6b1ba91" + "0bff85dc7a87ae9b5e98bd9afa775903324dbd6028f4e78f784b3765d769c05bf98b427b3511903b" + "2137e8a49b6f859d0af159ed6a86786aa634bd9afa775903324dbd6028f4e78f784b386d695cdf2d" + "4576e01bcaccf5e49e78da51af9955c0b8fa7606373b007994b3bd9afa775903324dbd6028f4e78f" + "784b3a4f74beafae2b9383ad8215d233a6cf3d057fb3c7e213e897beef4255faee9dbd9afa775903" + "324dbd6028f4e78f784b3ae76c45ca70e9180c1559981f42622dd251bca1fbe6b901c52ec11673b0" + "3514bd9afa775903324dbd6028f4e78f784b3be8e7eb348d35c1928f19c769846788991641d1f6cf" + "09514ca10269934f7359bd9afa775903324dbd6028f4e78f784b3e3926f0b8a15ad5a14167bb647a" + "843c3d4321e35dbc44dce8c837417f2d28b0bd9afa775903324dbd6028f4e78f784b400ac66d59b7" + "b094a9e30b01a6bd013aff1d30570f83e7592f421dbe5ff4ba8fbd9afa775903324dbd6028f4e78f" + "784b4185821f6dab5ba8347b78a22b5f9a0a7570ca5c93a74d478a793d83bac49805bd9afa775903" + "324dbd6028f4e78f784b41d1eeb177c0324e17dd6557f384e532de0cf51a019a446b01efb351bc25" + "9d77bd9afa775903324dbd6028f4e78f784b45876b4dd861d45b3a94800774027a5db45a48b2a729" + "410908b6412f8a87e95dbd9afa775903324dbd6028f4e78f784b4667bf250cd7c1a06b8474c613cd" + "b1df648a7f58736fbf57d05d6f755dab67f4bd9afa775903324dbd6028f4e78f784b47ff1b63b140" + "b6fc04ed79131331e651da5b2e2f170f5daef4153dc2fbc532b1bd9afa775903324dbd6028f4e78f" + "784b57e6913afacc5222bd76cdaf31f8ed88895464255374ef097a82d7f59ad39596bd9afa775903" + "324dbd6028f4e78f784b5890fa227121c76d90ed9e63c87e3a6533eea0f6f0a1a23f1fc445139bc6" + "bcdfbd9afa775903324dbd6028f4e78f784b5d1e9acbbb4a7d024b6852df025970e2ced66ff622ee" + "019cd0ed7fd841ccad02bd9afa775903324dbd6028f4e78f784b61cec4a377bf5902c0feaee37034" + "bf97d5bc6e0615e23a1cdfbae6e3f5fb3cfdbd9afa775903324dbd6028f4e78f784b631f0857b418" + "45362c90c6980b4b10c4b628e23dbe24b6e96c128ae3dcb0d5acbd9afa775903324dbd6028f4e78f" + "784b65b2e7cc18d903c331df1152df73ca0dc932d29f17997481c56f3087b2dd3147bd9afa775903" + "324dbd6028f4e78f784b66aa13a0edc219384d9c425d3927e6ed4a5d1940c5e7cd4dac88f5770103" + "f2f1bd9afa775903324dbd6028f4e78f784b6873d2f61c29bd52e954eeff5977aa8367439997811a" + "62ff212c948133c68d97bd9afa775903324dbd6028f4e78f784b6dbbead23e8c860cf8b47f74fbfc" + "a5204de3e28b881313bb1d1eccdc4747934ebd9afa775903324dbd6028f4e78f784b6dead13257df" + "c3ccc6a4b37016ba91755fe9e0ec1f415030942e5abc47f07c88bd9afa775903324dbd6028f4e78f" + "784b70a1450af2ad395569ad0afeb1d9c125324ee90aec39c258880134d4892d51abbd9afa775903" + "324dbd6028f4e78f784b72c26f827ceb92989798961bc6ae748d141e05d3ebcfb65d9041b266c920" + "be82bd9afa775903324dbd6028f4e78f784b781764102188a8b4b173d4a8f5ec94d828647156097f" + "99357a581e624b377509bd9afa775903324dbd6028f4e78f784b788383a4c733bb87d2bf51673dc7" + "3e92df15ab7d51dc715627ae77686d8d23bcbd9afa775903324dbd6028f4e78f784b78b4edcaabc8" + "d9093e20e217802caeb4f09e23a3394c4acc6e87e8f35395310fbd9afa775903324dbd6028f4e78f" + "784b7f49ccb309323b1c7ab11c93c955b8c744f0a2b75c311f495e18906070500027bd9afa775903" + "324dbd6028f4e78f784b82acba48d5236ccff7659afc14594dee902bd6082ef1a30a0b9b508628cf" + "34f4bd9afa775903324dbd6028f4e78f784b894d7839368f3298cc915ae8742ef330d7a26699f459" + "478cf22c2b6bb2850166bd9afa775903324dbd6028f4e78f784b8c0349d708571ae5aa21c1136348" + "2332073297d868f29058916529efc520ef70bd9afa775903324dbd6028f4e78f784b8d93d60c6919" + "59651476e5dc464be12a85fa5280b6f524d4a1c3fcc9d048cfadbd9afa775903324dbd6028f4e78f" + "784b9063f5fbc5e57ab6de6c9488146020e172b176d5ab57d4c89f0f600e17fe2de2bd9afa775903" + "324dbd6028f4e78f784b91656aa4ef493b3824a0b7263248e4e2d657a5c8488d880cb65b01730932" + "fb53bd9afa775903324dbd6028f4e78f784b91971c1497bf8e5bc68439acc48d63ebb8faabfd764d" + "cbe82f3ba977cac8cf6abd9afa775903324dbd6028f4e78f784b947078f97c6196968c3ae99c9a5d" + "58667e86882cf6c8c9d58967a496bb7af43cbd9afa775903324dbd6028f4e78f784b96e4509450d3" + "80dac362ff8e295589128a1f1ce55885d20d89c27ba2a9d00909bd9afa775903324dbd6028f4e78f" + "784b9783b5ee4492e9e891c655f1f48035959dad453c0e623af0fe7bf2c0a57885e3bd9afa775903" + "324dbd6028f4e78f784b97a51a094444620df38cd8c6512cac909a75fd437ae1e4d2292980766123" + "8127bd9afa775903324dbd6028f4e78f784b97a8c5ba11d61fefbb5d6a05da4e15ba472dc4c6cd49" + "72fc1a035de321342fe4bd9afa775903324dbd6028f4e78f784b992820e6ec8c41daae4bd8ab48f5" + "8268e943a670d35ca5e2bdcd3e7c4c94a072bd9afa775903324dbd6028f4e78f784b9954a1a99d55" + "e8b189ab1bca414b91f6a017191f6c40a86b6f3ef368dd860031bd9afa775903324dbd6028f4e78f" + "784b9baf4f76d76bf5d6a897bfbd5f429ba14d04e08b48c3ee8d76930a828fff3891bd9afa775903" + "324dbd6028f4e78f784b9c259fcb301d5fc7397ed5759963e0ef6b36e42057fd73046e6bd08b149f" + "751cbd9afa775903324dbd6028f4e78f784b9dd2dcb72f5e741627f2e9e03ab18503a3403cf6a904" + "a479a4db05d97e2250a9bd9afa775903324dbd6028f4e78f784b9ed33f0fbc180bc032f8909ca2c4" + "ab3418edc33a45a50d2521a3b5876aa3ea2cbd9afa775903324dbd6028f4e78f784ba4d978b7c4bd" + "a15435d508f8b9592ec2a5adfb12ea7bad146a35ecb53094642fbd9afa775903324dbd6028f4e78f" + "784ba924d3cad6da42b7399b96a095a06f18f6b1aba5b873b0d5f3a0ee2173b48b6cbd9afa775903" + "324dbd6028f4e78f784bad3be589c0474e97de5bb2bf33534948b76bb80376dfdc58b1fed767b5a1" + "5bfcbd9afa775903324dbd6028f4e78f784bb8d6b5e7857b45830e017c7be3d856adeb97c7290eb0" + "665a3d473a4beb51dcf3bd9afa775903324dbd6028f4e78f784bb93f0699598f8b20fa0dacc12cfc" + "fc1f2568793f6e779e04795e6d7c22530f75bd9afa775903324dbd6028f4e78f784bbb01da0333bb" + "639c7e1c806db0561dc98a5316f22fef1090fb8d0be46dae499abd9afa775903324dbd6028f4e78f" + "784bbc75f910ff320f5cb5999e66bbd4034f4ae537a42fdfef35161c5348e366e216bd9afa775903" + "324dbd6028f4e78f784bbdd01126e9d85710d3fe75af1cc1702a29f081b4f6fdf6a2b2135c0297a9" + "cec5bd9afa775903324dbd6028f4e78f784bbe435df7cd28aa2a7c8db4fc8173475b77e5abf392f7" + "6b7c76fa3f698cb71a9abd9afa775903324dbd6028f4e78f784bbef7663be5ea4dbfd8686e24701e" + "036f4c03fb7fcd67a6c566ed94ce09c44470bd9afa775903324dbd6028f4e78f784bc2469759c194" + "7e14f4b65f72a9f5b3af8b6f6e727b68bb0d91385cbf42176a8abd9afa775903324dbd6028f4e78f" + "784bc3505bf3ec10a51dace417c76b8bd10939a065d1f34e75b8a3065ee31cc69b96bd9afa775903" + "324dbd6028f4e78f784bc42d11c70ccf5e8cf3fb91fdf21d884021ad836ca68adf2cbb7995c10bf5" + "88d4bd9afa775903324dbd6028f4e78f784bc69d64a5b839e41ba16742527e17056a18ce3c276fd2" + "6e34901a1bc7d0e32219bd9afa775903324dbd6028f4e78f784bcb340011afeb0d74c4a588b36eba" + "a441961608e8d2fa80dca8c13872c850796bbd9afa775903324dbd6028f4e78f784bcc8eec6eb921" + "2cbf897a5ace7e8abeece1079f1a6def0a789591cb1547f1f084bd9afa775903324dbd6028f4e78f" + "784bcf13a243c1cd2e3c8ceb7e70100387cecbfb830525bbf9d0b70c79adf3e84128bd9afa775903" + "324dbd6028f4e78f784bd89a11d16c488dd4fbbc541d4b07faf8670d660994488fe54b1fbff2704e" + "4288bd9afa775903324dbd6028f4e78f784bd9668ab52785086786c134b5e4bddbf72452813b6973" + "229ab92aa1a54d201bf5bd9afa775903324dbd6028f4e78f784bda3560fd0c32b54c83d4f2ff8690" + "03d2089369acf2c89608f8afa7436bfa4655bd9afa775903324dbd6028f4e78f784bdf02aab48387" + "a9e1d4c65228089cb6abe196c8f4b396c7e4bbc395de136977f6bd9afa775903324dbd6028f4e78f" + "784bdf91ac85a94fcd0cfb8155bd7cbefaac14b8c5ee7397fe2cc85984459e2ea14ebd9afa775903" + "324dbd6028f4e78f784be051b788ecbaeda53046c70e6af6058f95222c046157b8c4c1b9c2cfc65f" + "46e5bd9afa775903324dbd6028f4e78f784be36dfc719d2114c2e39aea88849e2845ab326f6f7fe7" + "4e0e539b7e54d81f3631bd9afa775903324dbd6028f4e78f784be39891f48bbcc593b8ed86ce82ce" + "666fc1145b9fcbfd2b07bad0a89bf4c7bfbfbd9afa775903324dbd6028f4e78f784be6856f137f79" + "992dc94fa2f43297ec32d2d9a76f7be66114c6a13efc3bcdf5c8bd9afa775903324dbd6028f4e78f" + "784beaff8c85c208ba4d5b6b8046f5d6081747d779bada7768e649d047ff9b1f660cbd9afa775903" + "324dbd6028f4e78f784bee83a566496109a74f6ac6e410df00bb29a290e0021516ae3b8a23288e7e" + "2e72bd9afa775903324dbd6028f4e78f784beed7e0eff2ed559e2a79ee361f9962af3b1e999131e3" + "0bb7fd07546fae0a7267bd9afa775903324dbd6028f4e78f784bf1b4f6513b0d544a688d13adc291" + "efa8c59f420ca5dcb23e0b5a06fa7e0d083dbd9afa775903324dbd6028f4e78f784bf2a16d35b554" + "694187a70d40ca682959f4f35c2ce0eab8fd64f7ac2ab9f5c24abd9afa775903324dbd6028f4e78f" + "784bf31fd461c5e99510403fc97c1da2d8a9cbe270597d32badf8fd66b77495f8d94bd9afa775903" + "324dbd6028f4e78f784bf48e6dd8718e953b60a24f2cbea60a9521deae67db25425b7d3ace3c517d" + "d9b7bd9afa775903324dbd6028f4e78f784bc805603c4fa038776e42f263c604b49d96840322e192" + "2d5606a9b0bbb5bffe6fbd9afa775903324dbd6028f4e78f784b1f16078cce009df62edb9e7170e6" + "6caae670bce71b8f92d38280c56aa372031dbd9afa775903324dbd6028f4e78f784b37a480374daf" + "6202ce790c318a2bb8aa3797311261160a8e30558b7dea78c7a6bd9afa775903324dbd6028f4e78f" + "784b408b8b3df5abb043521a493525023175ab1261b1de21064d6bf247ce142153b9bd9afa775903" + "324dbd6028f4e78f784b540801dd345dc1c33ef431b35bf4c0e68bd319b577b9abe1a9cff1cbc39f" + "548fbd9afa775903324dbd6028f4e78f784b040b3bc339e9b6f9acd828b88f3482a5c3f64e67e5a7" + "14ba1da8a70453b34af6bd9afa775903324dbd6028f4e78f784b1142a0cc7c9004dff64c5948484d" + "6a7ec3514e176f5ca6bdeed7a093940b93ccbd9afa775903324dbd6028f4e78f784b288878f12e8b" + "9c6ccbf601c73d5f4e985cac0ff3fcb0c24e4414912b3eb91f15bd9afa775903324dbd6028f4e78f" + "784b2ea4cb6a1f1eb1d3dce82d54fde26ded243ba3e18de7c6d211902a594fe56788bd9afa775903" + "324dbd6028f4e78f784b40d6cae02973789080cf4c3a9ad11b5a0a4d8bba4438ab96e276cc784454" + "dee7bd9afa775903324dbd6028f4e78f784b4f0214fce4fa8897d0c80a46d6dab4124726d136fc24" + "92efd01bfedfa3887a9cbd9afa775903324dbd6028f4e78f784b5c2afe34bd8a7aebbb439c251dfb" + "6a424f00e535ac4df61ec19745b6f10e893abd9afa775903324dbd6028f4e78f784b99d7ada0d67e" + "5233108dbd76702f4b168087cfc4ec65494d6ca8aba858febadabd9afa775903324dbd6028f4e78f" + "784ba608a87f51bdf7532b4b80fa95eadfdf1bf8b0cbb58a7d3939c9f11c12e71c85bd9afa775903" + "324dbd6028f4e78f784bbdd4086c019f5d388453c6d93475d39a576572baff75612c321b46a35a53" + "29b1bd9afa775903324dbd6028f4e78f784bcb994b400590b66cbf55fc663555caf0d4f1ce267464" + "d0452c2361e05ee1cd50bd9afa775903324dbd6028f4e78f784bd6ee8db782e36caffb4d9f820790" + "0487de930aabcc1d196fa455fbfd6f37273dbd9afa775903324dbd6028f4e78f784bdda0121dcf16" + "7db1e2622d10f454701837ac6af304a03ec06b3027904988c56bbd9afa775903324dbd6028f4e78f" + "784be42572afac720f5d4a1c7aaaf802f094daceb682f4e92783b2bb3fa00862af7fbd9afa775903" + "324dbd6028f4e78f784be6236dc1ee074c077c7a1c9b3965947430847be125f7aeb71d91a128133a" + "ea7fbd9afa775903324dbd6028f4e78f784bef87be89a413657de8721498552cf9e0f3c1f71bc62d" + "fa63b9f25bbc66e86494bd9afa775903324dbd6028f4e78f784bf5e892dd6ec4c2defa4a495c0921" + "9b621379b64da3d1b2e34adf4b5f1102bd39bd9afa775903324dbd6028f4e78f784bd4241190cd5a" + "369d8c344c660e24f3027fb8e7064fab33770e93fa765ffb152ebd9afa775903324dbd6028f4e78f" + "784b23142e14424fb3ff4efc75d00b63867727841aba5005149070ee2417df8ab799bd9afa775903" + "324dbd6028f4e78f784b91721aa76266b5bb2f8009f1188510a36e54afd56e967387ea7d0b114d78" + "2089bd9afa775903324dbd6028f4e78f784bdc8aff7faa9d1a00a3e32eefbf899b3059cbb313a48b" + "82fa9c8d931fd58fb69dbd9afa775903324dbd6028f4e78f784b9959ed4e05e548b59f219308a455" + "63ea85bb224c1ad96dec0e96c0e71ffccd81bd9afa775903324dbd6028f4e78f784b47b31a1c7867" + "644b2ee8093b2d5fbe21e21f77c1617a2c08812f57ace0850e9fbd9afa775903324dbd6028f4e78f" + "784bfabc379df395e6f52472b44fa5082f9f0e0da480f05198c66814b7055b03f446bd9afa775903" + "324dbd6028f4e78f784be37ff3fc0eff20bfc1c060a4bf56885e1efd55a8e9ce3c5f4869444cacff" + "ad0bbd9afa775903324dbd6028f4e78f784b4cdae3920a512c9c052a8b4aba9096969b0a0197b614" + "031e4c64a5d898cb09b9bd9afa775903324dbd6028f4e78f784b5b89f1aa2435a03d18d9b203d17f" + "b4fba4f8f5076cf1f9b8d6d9b826222235c1bd9afa775903324dbd6028f4e78f784b007f4c951257" + "13b112093e21663e2d23e3c1ae9ce4b5de0d58a297332336a2d8bd9afa775903324dbd6028f4e78f" + "784be060da09561ae00dcfb1769d6e8e846868a1e99a54b14aa5d0689f2840cec6dfbd9afa775903" + "324dbd6028f4e78f784b48f4584de1c5ec650c25e6c623635ce101bd82617fc400d4150f0aee2355" + "b4cabd9afa775903324dbd6028f4e78f784baf79b14064601bc0987d4747af1e914a228c05d622ce" + "da03b7a4f67014fee767bd9afa775903324dbd6028f4e78f784bc3d65e174d47d3772cb431ea599b" + "ba76b8670bfaa51081895796432e2ef6461fbd9afa775903324dbd6028f4e78f784b1e918f170a79" + "6b4b0b1400bb9bdae75be1cf86705c2d0fc8fb9dd0c5016b933bbd9afa775903324dbd6028f4e78f" + "784b66d0803e2550d9e790829ae1b5f81547cc9bfbe69b51817068ecb5dabb7a89fcbd9afa775903" + "324dbd6028f4e78f784b284153e7d04a9f187e5c3dbfe17b2672ad2fbdd119f27bec789417b79198" + "53ecbd9afa775903324dbd6028f4e78f784bedd2cb55726e10abedec9de8ca5ded289ad793ab3b69" + "19d163c875fec1209cd5bd9afa775903324dbd6028f4e78f784b90aec5c4995674a849c1d1384463" + "f3b02b5aa625a5c320fc4fe7d9bb58a62398" +) -TEST_CERTIFICATE_PFX = "308217690201033082172506092a864886f70d010701a0821716048217123082170e3082060f0609" \ - "2a864886f70d010701a0820600048205fc308205f8308205f4060b2a864886f70d010c0a0102a082" \ - "04fe308204fa301c060a2a864886f70d010c0103300e0408162a440713bbbc1f020207d0048204d8" \ - "ad9628f0b98e0e58d7c07a6f77718bf3f10162c54cad4adde749ff011ded1734ef98f228fe6d7b86" \ - "d34ab41f2d42eb2d34538d9b11a3df9aa11a749670716f7d4246acb807b1316863b10280eb7c627a" \ - "49681f192015fd4da730a84c01da14f36c36f4024469a822a51df48f2cbba381712c8a842ee58b4e" \ - "e5553f600576cd67884a26bc0343e7a20656f121700041a2c644fa6dfaa43bfc114dff1d5cf8661d" \ - "9392d17365ee567d7a736129ee4d196384d58f8089a7964deb0b458e21bbafa633651ff2305e87ba" \ - "823d987fa86743d579a55eb197b6f7a1c2ffc5288ebdcc280014bfc01f5f84c4b6552fae7aa2c34b" \ - "63ff2f2d31a00ac90d157bac3a609951ba0eadd4ed90efdac4449e94275a50f4a401378f7d92c197" \ - "367c76a09e1e20a225a90603b8c543f319b0ca84d60b829173883bd3090361ad85f004ca774c4869" \ - "7983badc9cd2f98760db5cdac27ed28bbc3d46603af03d2e890b2e6fea0b935370eef6b1ca6b045b" \ - "32a86f769a1e81a638200f9682e982a8210d0bb153e826ffe8cb7e4db1b012e7b6ee5e89029f8e0a" \ - "e6130423ddbe46266f6f325635f586100d9f1459ffcb1ca7fbb132c97c3c6c0205ab23f4ee11a726" \ - "967ef35231d787e58c79ad8e1338cd58809add4ecf1cc7b7e200ca9ded45d646a279ee09cf7c929d" \ - "ece2cac6d4971831a1dea5d809b52e25f9726d698f035053fbae60b5fd3dba3ecacb6ceb3a21ff99" \ - "667b7598b1700c497534c8734365660a3257904cbd3c733165a2559194bacf01991c389e0f10658c" \ - "7af4ff97616ebd9e2058e4d6ba518e3ed53e10d904481b88345a2381a5f6f00e8a0fa9d3895819ed" \ - "4daee60c2cec99c434a8e99a585dd9ff62a19592a90f3fb561c708e5221fc2c20948720e0d80abb9" \ - "f6bc159bc412632591e0b6c77d78d3373d3333add6e182526090d1c86d06b33a9d02334f014cd879" \ - "93943f71666bef084afc84198c82d31d91c1d5cdeb3f680eaa05b6ebfae13b7a5e8f5b846ea885c4" \ - "975925a91b7665eb3e278edc296ea6855492dcead93cdae2762064572e5cd371d95069886c338799" \ - "50884d266fcbcab63c534dc5bfcc43e9ef817b7fab1e9ccd24e7622a4d729725108febef8cb25afc" \ - "1a9be020bc38233b04d16129179bc36dd407e4fc541610d23c7a3d25cf162efa47d3c9209b83ce94" \ - "d96b1d2c98c9bc40f53bb2620527c69fff18b8ff5adc0860997bf11c3d7f362127dae5445d707c12" \ - "2ad52d279d36150f4233095502693091643c9d82cf903086054da9fe720ace9021399fd3877bb382" \ - "c8ddb47fb50ab4adea7e76c81bcd0c561595666d684bbf26a78aa89e908e17fd80f9d2eb75501908" \ - "490ab70c9c4af5d0a38ad3443e1adbbf17216fd23d3738757d7a81bf4c864e4129144228cb85c0a2" \ - "41e4dc3ed90c46c938c479083d5e7112257019fc981e6bdf21a9fdc28eb09ee419b2f1812493d483" \ - "6b3b61119dbdd07043ee119173a5a1b486115f7d93364075cf294ffd67e29e602864e9a7bba5b81e" \ - "9f204aa7b7cbbed773d1aa6817926641e3b3a987dfc0d53850a5fa11bc9e3cc435bc3dda735743c5" \ - "5147bcaacff64578f1f234d20fbe335a4badeba349a6ea52eca33937922f3cf738ac3f6d56205c4c" \ - "89be9e9d160a1302fe397507ce14cbae89cbf7ee9246fe466d026b5221ae186cc7279172220e4a04" \ - "770b54a10490089faf7936133612aac0097cd409991d6225697d1efb94ec8ffceda5466aec8aae92" \ - "3181e2300d06092b06010401823711023100301306092a864886f70d010915310604040100000030" \ - "5d06092a864886f70d01091431501e4e00740065002d00310065003600350061003200630039002d" \ - "0030003500390030002d0034003800610031002d0062003300380035002d00390035003700370062" \ - "0065006600620039006600630033305d06092b060104018237110131501e4e004d00690063007200" \ - "6f0073006f0066007400200053006f0066007400770061007200650020004b006500790020005300" \ - "74006f0072006100670065002000500072006f00760069006400650072308210f706092a864886f7" \ - "0d010706a08210e8308210e4020100308210dd06092a864886f70d010701301c060a2a864886f70d" \ - "010c0103300e0408c0fd959d9d9f63bd020207d0808210b0d375930863be8faf4e0d8a59a9417eb2" \ - "9e6248ad88e796ab92e17ef2147d31c135f01b1d7cd81b57bb6f23de0da34fd25efc061837ebd828" \ - "53fd96f8cb1337d43e6049a4a6a272204b8a277f7fb0e5dff6eecbfcad1b06b76184755ba61faf94" \ - "bef263b2c3d0856e4fbeb90354678e227e5cca56f868daa5b905320848dd489506c62db57321c2ae" \ - "8a419fd08c2efa948e75c3f8ae1fce19ca1c22d5788bdeb4df47ca09c33e3eb1cd3bfb3e2289305d" \ - "f31fe994cad6e22bd3bc0b8720850d8a954cafaca210af3be89ba7acdb72c357bb602630b62803d6" \ - "e46d8506a4157495f35e90b479fc3f8f78915fb98401370e78a4a90a465fa45dc64a2d736a309af9" \ - "e3a201ee5a53a3bfdae945285a437ec18de88728f184fefb9af8ddfae947dcfccb7fda5945ff7370" \ - "6b057c4d2418c87ee7bcafb3d8580ee9720e1f493dd4fc875944b50b33058fed37f3e373d480dfa1" \ - "52846159d9bcd209536356789690fbedaed386a1777511b791220ca265f38207a6f5c4773b94b445" \ - "5c94e28f6a6edbbd136fc186da121f6f73e79d37be14eaf5f0867b9275a4626da314dd63f45207ec" \ - "ab78b94761438e82ec947f97c4ef08981b0757fcf468cda62cfd4e9b9bada0aab15aff55fabe1835" \ - "37dfe4a3764fe9d95adcddd9ecf5f29dad1a2ca13ef8d3c51a7790138bd41994d62adc181f4df4e4" \ - "fc6a3064d42f51379343132ab4fb51014eb7b8473d216c2fd48921572deb75db8399ad31755c19ef" \ - "3c32ac17a89be5d32801c0e188e210014416b243b2b60d53a0c50e78954c23369355dd4376e723c1" \ - "d801e7fbe1429d865a1d6ac68853996db478c332fc764b6b0477ba61699b7222c2a6bb346534d576" \ - "cf399bb677fb6fc5378dbb53821783b3487be08f4f390e56d32d40f83ce40ef8db5490224df2329f" \ - "f0e573c85e3ea01049704b74ce33a7dbd93a01c3bee19c095927e0ebcc7aa36c57fb5467b20a8f10" \ - "b64da6ee21db688ead98671784d9972a155568268b372c9cfaa86e6d5b58f7e345d66751614d7740" \ - "f449c7f7b50e63b2d2d441c77d32997f17a1c62636b9855a238cfc1cad090dbe906882b1985fb814" \ - "b4b5ecf73a0f19fac21ffbc93a1cb618c4d6bac70a9d0df562b0d63d6c3f0f6e352c2c3d45af9c11" \ - "b9b68ed0481fdf1f3dd326b31b3ead81128a0ad1b481e48cb2615df6be7c595f11d679abada7c9ac" \ - "78f63867372b9861e97c24dedd1f11d0c26ede74d101af10c0c53e6ce423ebf8fa3d61600f0fe381" \ - "923ea8638382afa6144dbec8ef980beb856ea34541ebc708af409256df0c9d8a667739cb57641cbe" \ - "f9e35d497929ee67e4a77296c8c020b3eeda0ab81c77bd43536c82c130dd657a570e78a695a0007e" \ - "1470e8d66be7a20b87de45d5e89e5c403892ec48460f156db05141f2a4a15d53c02ad0dedb371d7d" \ - "b9c5e41130d7924130b9573943a5b4574b1f229e8867ef2bd58a3df0c59358407b416b411098da16" \ - "036831c54a8368b2479bb90e6b7c28ed1b5a1db5e12b4aa6b6a1bc86ae615eb3b1d6ae9e7a6f420d" \ - "48f34f95bb953ef29242b12263660b9a590172ce21c8bdce6bdc284512708a318cf015fcc52e016b" \ - "e3571af346ac3f5bf7a65529e78670c75f9782d55a610baa39e728f0d11ab153a1b86b6b1f480c33" \ - "7ca56975ca49e70867c6e2a396c5fd8fb61f4b7a3b75e1f1e82a8fbdb5a47daa631df4e2d2bbd283" \ - "a0b1687e71d9371d23fe1e39d5d8bb70c2a734f88d69a3691beeea8953f8862eb3e3619e173b40e6" \ - "81bd95f01858b596c6f7162753a880fe6174c550dab1d6b94cde227216552cb14ee6caeaadf4c5bc" \ - "5994570c7e8308665e6e789308bb16aa1996bc58daafa45767bd51480415497d321b587addb0664c" \ - "c8ecf217f70c17dc2b3b437bb371129598bd11165d7e023ec5bfd2da72a379eac8e19ebef1ba23a8" \ - "eaaf3ab712e2e1cc30e6bfe17b619b30167c4c613e8de82a95ee3135829c53dde747fc1faa90d290" \ - "f05d820b347ed7076abd24e8091b360c3277d7f59903b5f5fa636c63a34c9b59c2d353ee160555d7" \ - "c4dbe72d3252edc6aacc717a8ca87c150c156103b5a635696c0d12acbcab6138dcb548f01cce73f5" \ - "7b964eb1ed6b38b15aac4c566e058b91a2ab38fcb8d90211a4a06aa18b7c02145bed5584deeddf66" \ - "e9837e88b4deddc56e5cd73f51159541cdace7424a71fd11d547a4361c7a4c4ae78de4ec70fdebeb" \ - "3e429b79cd65c058e06a22ca070287a8b59738f19d52672de8f54aadb9b2b6a5f05f78e1f1f515ff" \ - "9ccea9dc957e0e1ad659b207f5980028fe2771c4652adcb39d899abbaef5c61323fc5d326c4afc8d" \ - "a99bb8144c24b60f7de03a2e907d839ad1ab286c53dfda3ca481a2cf958005eb4e24b7819b441c97" \ - "c8c9801c46864714e2af4eacf36954b13e400c75b73b6e9eeefe593c9122070304287b1c7ed06e75" \ - "d0801b098ace8efa33434f4578a1da6d17cafe33dc0ec690d9af484a1bb6d12758ce7cfa66935376" \ - "907a822496e7ad7f1508d9c7367a672bff9f97fcce9c0cccb995b4ed1bf6b3a361afad133c804c5a" \ - "e7b72e3ae5565eb56ce6df53dfcb6c1fdec116ec93e38c1dda9793e4c182cf3e90b6db307fa35d46" \ - "8078675c9fe5a27b8445d0b23a4b628e676fd8ee4e0b0ed555e37e34be82f37f140ba15073d494c8" \ - "ae1280907c7477f300bb7fcbb936b2105e5d00cbc39853ae9bb424e3d9c07ba873637fee4c33eaf1" \ - "7cbbb6ca6d2abab12dc7a75f4004aa75efde94465883d85faf201959678bf73929bf8f2f0403b9d4" \ - "c20fe6f8967a979809706bdba48859d1ce710129118f57234599a3e22270e035a7722404e50c5784" \ - "4d729690b9749e3786b969fd783ec7a8c008d9ddb2fad1bcaae1995dec82a3ee8092c269333392a5" \ - "46de7b949a7cb65a6bf1adc89dc5515bef8819d8dee3341792db070066aacbf60da2dd5b8ab47f2e" \ - "4bdd00762e8847f47ebd2241120c0616df6fd6e5ea854267a0fe3c802910ea843b64831d94b48818" \ - "2c54bf7ea3bcfd77fa41124a2858ff8bdf81378904aff993ea3b1a211fb65c2df8b78d34d8f4b3a0" \ - "9e8b474d1ab8d5d7d332b150ce5db7d720a18cbbee9bd5b2db243a678e90600a66e5ef7280128e9a" \ - "35ea8aa0c095b8507e87cb980d2e7a04d4bc047ab145314b2b235558e1e396f2a648738a77a9839a" \ - "e37985c13051e3d7aa4b05b90be338c34fbb7ab6c142896635466c091f0f296756b1ed19558d16e0" \ - "38a59f5cfd120e96d79dc44cc16cd8e5250b1d61bb2a714802c1a87ba0fb5e70677c7a0fc4bca3b9" \ - "24ce793d78c3b0359725d4c588bd60066dcf0a23c8a86990200bec5ca54796de29e10fbf77f5eea1" \ - "43a38e6a6e1fea0b03c95cfa224edf2ac1867c142b64fe90179b023fe1f50005538cd8a92dfefbca" \ - "75d8e3ec492d53b5aeadd72981328542eb0903aaf2fc09daaf27fe4fc8b5cca6af18e0026cd2f244" \ - "d8aafbfb11f0270ba511c4b0d805d5088d6a4a3a59aeb2361ae3027cb5b902ed55fde38c164ca450" \ - "013bf02d2483a1b61f2bedd31966bbf8dd1c972ef029dd3dd3b74fe78d6ac1edb98d1815a22f3bcc" \ - "c206d470c26797d2917ed5316b956c6e928e159294d41d478a40a4af2acd3a294b3be55fa50e44bf" \ - "e9785dd5383ea759777cfb7b9d316fc40c9abf1f6d5b34f89e433395b0bf5e07e6962ea278e22b4a" \ - "da97db479201472722c682292a1f0107e12c8e1348aff941bb5158da7ca9bface061b22e22e8ba9f" \ - "9700af4a155b7bc378dcca96d9aee391a6349be9c668f40b2dc4107c76239b4fd89cec57c334e603" \ - "4e6afa183015d5010f296457f9d0f04713296b73095165c81601e36dc962d0527dc5a81593821f62" \ - "292fd1fab21d2fc3a2f884e0a9689ceb2eade3486e8d976b65684d40954d681f94df9992a273c915" \ - "383786ec557d8f41c42a2efea133b57946f45ea1b627d5a79c72daca84ffbb811ab37874086e25e5" \ - "b1601e0038505fca4394258c60075dab3285fca7b3e267c66731f1b165607b937c4606baee2d2dbe" \ - "0397c623bbfee94bc3c42a579100daeb867efd9ddc49e0ea5881898c733d5aa122a9a6ad9d5e6009" \ - "20dd674466d5886d94e6346c56a55af08218e136fc2a3849ec60e95f9d1b6df81517007f9bca7b84" \ - "e624a09f4be514cfb3e3dff2f00436aa19571a1e4674785a15d31aaf01a2091f3e752b29638e84ab" \ - "7e5bc993086ef027c9aa311464189d9c63659691367fa5c56c2cf4e1b485b55dad9678aa85529092" \ - "2734abb7b398f1dcf82a52960b21661bf32b783a40f86ad013ad573c64a02743427b9e4ce0eb703a" \ - "9280de7471bb03fa8a5a57c6025bc277fd28616040ebfae77471e988f8feb5a2db90f8c5a3fc4b3b" \ - "d0b3f2ffd239966dbff3431bcfd5afd18d6bfc100c7d4476b264c636e2c73e5aa42cec510e0897b9" \ - "465b3dfa6e7ac9686d5f6484cfe908f751909c3f095872645b9fd4f21776a713bd1b574c250c7012" \ - "cdf8e16fe1140fed49fc8db0185cbafb347cf2c4538ff867061bb37ed0b1c324f99c46764f93a345" \ - "488279b787276688981c7c4519447f0468ae1d9b21f6b232ca8f9c6b58b1262e5634ffcc3d87db73" \ - "4580a28b6944703eeb6f01f624e113606df3b0128a6e546a0fdf83c0fd265b72ed8158968cf1f807" \ - "0eec6ca64376c84985a7d1de07b201bd6cc7312067b692e6d43fcbe9555632ebe33070f04497c96e" \ - "263c9766af8b336cd939e9c51351551c26536289f61b2a01408056a097d760238bcfc355f052d0e6" \ - "edf3f4910525ccb4b9c92f54af067a9624d064719b7f7e6ee05065f2575913c78b25b743c474a289" \ - "4256013b24d5dcc65e439adca947c4bc624655f25a3d60a08367846717d66d7626d2bb9e104bcdaa" \ - "9ce7a6d06354d306bdf891de3e563d2132083028c79d2c5624f9a39075bd2923dd34d071ed678c25" \ - "9d96714f8ac55ca965cde19e3081ef7f955e24c035bc125a7f43c7986dcbbfcfac8dec2af5ae3d95" \ - "e88e6b8e11bd323221a2d247e3ad39d894466dffc0d77f4dd01667d11f219d2fa78945a74bec99d5" \ - "770960bece320ce82e0fa1a82378c52b1d3f88dd250a630e3c114a12f0f6a591ed9d6e82644c7c51" \ - "54d46579acf60996704bead6998623403e978b04b3dd0b923d8a7d2ee79e482ea804c21a7eed2fa9" \ - "7f5ae85e34bcf9cea425b73ff306986bdae5b7d94b5b1a534a76afb4b9663813b3de1048aca6e1f1" \ - "87805ba66b511d7a2a47c24ec66f2b96898e2f7436fd750c1f349ecf5c546d8d39c440074ee84aff" \ - "109cdb0eb35d3e3c7c11abdc6ad1cc2ab386480bad679b503c3877033628d0e07d5429a1cfd71b94" \ - "97d65dc90ce540718383a3657dfe4e6c305633dc0698d02777fb898a8ca0ddcea37c96d405067e23" \ - "477fe636c26b086bceb02443080b8837f4350640d7ebeb227ac6e71ecb8140e129dd6b9db5bea5bd" \ - "eac8aac6ab7b8311127e516dd0bec2747a1ecaeaf3794407d0a73e315dac690850808c94bcbc49b8" \ - "8b272ff59373c5cf9a8e0c442c0eb7829faa1f1c394e566ea444d523194bd1547b56cfbaec82aa05" \ - "d8909697c49f066f28484a8c7bb4c34584946084e294532c9bd704a8e125f1ede4fa86604c9d2109" \ - "12d2326a94ff1edbba1231c848b84f5f9399b17b600cf1586e9efe686686e7f449ce3f820f051583" \ - "4508f1cf10efcffd014cb65cba99a8534f6ae2c987fc69f152e70ce03b32663dd485015a0d956cfd" \ - "9696588b45674b42f8eb6d58a167de1003c2144d1fde87e1097fa4264b1e0249fb2bec3c780094f6" \ - "c73b2a69a1e9c5806ad26ea0fbcfb68dcc2970b0e913b5ed41654366202230096abf925df05dd9c2" \ - "cf706127364ed8519d8bc51de85887db051b22e1de6ee18849cb85188d453952d02d5b7717257b49" \ - "9292446f68dbece07c5422e790f40b3f21f996133e0c62fc6046c003aa4c679fc924556c45623378" \ - "10d1b60fd750fbc1ebc9a9ae9c66ed4b94c790dbbdae6b81ede8ced06c33fe5da09b99e82b9195bc" \ - "d60b4502fc7384fe1fd9d30bfccb27ba303b301f300706052b0e03021a0414809543226a23c6d9d8" \ - "e1c872577d5ef35c4e87c10414b0e8c9d74969d069f12daa9d61e381229ea02dc4020207d0" +TEST_CERTIFICATE_PFX = ( + "308217690201033082172506092a864886f70d010701a0821716048217123082170e3082060f0609" + "2a864886f70d010701a0820600048205fc308205f8308205f4060b2a864886f70d010c0a0102a082" + "04fe308204fa301c060a2a864886f70d010c0103300e0408162a440713bbbc1f020207d0048204d8" + "ad9628f0b98e0e58d7c07a6f77718bf3f10162c54cad4adde749ff011ded1734ef98f228fe6d7b86" + "d34ab41f2d42eb2d34538d9b11a3df9aa11a749670716f7d4246acb807b1316863b10280eb7c627a" + "49681f192015fd4da730a84c01da14f36c36f4024469a822a51df48f2cbba381712c8a842ee58b4e" + "e5553f600576cd67884a26bc0343e7a20656f121700041a2c644fa6dfaa43bfc114dff1d5cf8661d" + "9392d17365ee567d7a736129ee4d196384d58f8089a7964deb0b458e21bbafa633651ff2305e87ba" + "823d987fa86743d579a55eb197b6f7a1c2ffc5288ebdcc280014bfc01f5f84c4b6552fae7aa2c34b" + "63ff2f2d31a00ac90d157bac3a609951ba0eadd4ed90efdac4449e94275a50f4a401378f7d92c197" + "367c76a09e1e20a225a90603b8c543f319b0ca84d60b829173883bd3090361ad85f004ca774c4869" + "7983badc9cd2f98760db5cdac27ed28bbc3d46603af03d2e890b2e6fea0b935370eef6b1ca6b045b" + "32a86f769a1e81a638200f9682e982a8210d0bb153e826ffe8cb7e4db1b012e7b6ee5e89029f8e0a" + "e6130423ddbe46266f6f325635f586100d9f1459ffcb1ca7fbb132c97c3c6c0205ab23f4ee11a726" + "967ef35231d787e58c79ad8e1338cd58809add4ecf1cc7b7e200ca9ded45d646a279ee09cf7c929d" + "ece2cac6d4971831a1dea5d809b52e25f9726d698f035053fbae60b5fd3dba3ecacb6ceb3a21ff99" + "667b7598b1700c497534c8734365660a3257904cbd3c733165a2559194bacf01991c389e0f10658c" + "7af4ff97616ebd9e2058e4d6ba518e3ed53e10d904481b88345a2381a5f6f00e8a0fa9d3895819ed" + "4daee60c2cec99c434a8e99a585dd9ff62a19592a90f3fb561c708e5221fc2c20948720e0d80abb9" + "f6bc159bc412632591e0b6c77d78d3373d3333add6e182526090d1c86d06b33a9d02334f014cd879" + "93943f71666bef084afc84198c82d31d91c1d5cdeb3f680eaa05b6ebfae13b7a5e8f5b846ea885c4" + "975925a91b7665eb3e278edc296ea6855492dcead93cdae2762064572e5cd371d95069886c338799" + "50884d266fcbcab63c534dc5bfcc43e9ef817b7fab1e9ccd24e7622a4d729725108febef8cb25afc" + "1a9be020bc38233b04d16129179bc36dd407e4fc541610d23c7a3d25cf162efa47d3c9209b83ce94" + "d96b1d2c98c9bc40f53bb2620527c69fff18b8ff5adc0860997bf11c3d7f362127dae5445d707c12" + "2ad52d279d36150f4233095502693091643c9d82cf903086054da9fe720ace9021399fd3877bb382" + "c8ddb47fb50ab4adea7e76c81bcd0c561595666d684bbf26a78aa89e908e17fd80f9d2eb75501908" + "490ab70c9c4af5d0a38ad3443e1adbbf17216fd23d3738757d7a81bf4c864e4129144228cb85c0a2" + "41e4dc3ed90c46c938c479083d5e7112257019fc981e6bdf21a9fdc28eb09ee419b2f1812493d483" + "6b3b61119dbdd07043ee119173a5a1b486115f7d93364075cf294ffd67e29e602864e9a7bba5b81e" + "9f204aa7b7cbbed773d1aa6817926641e3b3a987dfc0d53850a5fa11bc9e3cc435bc3dda735743c5" + "5147bcaacff64578f1f234d20fbe335a4badeba349a6ea52eca33937922f3cf738ac3f6d56205c4c" + "89be9e9d160a1302fe397507ce14cbae89cbf7ee9246fe466d026b5221ae186cc7279172220e4a04" + "770b54a10490089faf7936133612aac0097cd409991d6225697d1efb94ec8ffceda5466aec8aae92" + "3181e2300d06092b06010401823711023100301306092a864886f70d010915310604040100000030" + "5d06092a864886f70d01091431501e4e00740065002d00310065003600350061003200630039002d" + "0030003500390030002d0034003800610031002d0062003300380035002d00390035003700370062" + "0065006600620039006600630033305d06092b060104018237110131501e4e004d00690063007200" + "6f0073006f0066007400200053006f0066007400770061007200650020004b006500790020005300" + "74006f0072006100670065002000500072006f00760069006400650072308210f706092a864886f7" + "0d010706a08210e8308210e4020100308210dd06092a864886f70d010701301c060a2a864886f70d" + "010c0103300e0408c0fd959d9d9f63bd020207d0808210b0d375930863be8faf4e0d8a59a9417eb2" + "9e6248ad88e796ab92e17ef2147d31c135f01b1d7cd81b57bb6f23de0da34fd25efc061837ebd828" + "53fd96f8cb1337d43e6049a4a6a272204b8a277f7fb0e5dff6eecbfcad1b06b76184755ba61faf94" + "bef263b2c3d0856e4fbeb90354678e227e5cca56f868daa5b905320848dd489506c62db57321c2ae" + "8a419fd08c2efa948e75c3f8ae1fce19ca1c22d5788bdeb4df47ca09c33e3eb1cd3bfb3e2289305d" + "f31fe994cad6e22bd3bc0b8720850d8a954cafaca210af3be89ba7acdb72c357bb602630b62803d6" + "e46d8506a4157495f35e90b479fc3f8f78915fb98401370e78a4a90a465fa45dc64a2d736a309af9" + "e3a201ee5a53a3bfdae945285a437ec18de88728f184fefb9af8ddfae947dcfccb7fda5945ff7370" + "6b057c4d2418c87ee7bcafb3d8580ee9720e1f493dd4fc875944b50b33058fed37f3e373d480dfa1" + "52846159d9bcd209536356789690fbedaed386a1777511b791220ca265f38207a6f5c4773b94b445" + "5c94e28f6a6edbbd136fc186da121f6f73e79d37be14eaf5f0867b9275a4626da314dd63f45207ec" + "ab78b94761438e82ec947f97c4ef08981b0757fcf468cda62cfd4e9b9bada0aab15aff55fabe1835" + "37dfe4a3764fe9d95adcddd9ecf5f29dad1a2ca13ef8d3c51a7790138bd41994d62adc181f4df4e4" + "fc6a3064d42f51379343132ab4fb51014eb7b8473d216c2fd48921572deb75db8399ad31755c19ef" + "3c32ac17a89be5d32801c0e188e210014416b243b2b60d53a0c50e78954c23369355dd4376e723c1" + "d801e7fbe1429d865a1d6ac68853996db478c332fc764b6b0477ba61699b7222c2a6bb346534d576" + "cf399bb677fb6fc5378dbb53821783b3487be08f4f390e56d32d40f83ce40ef8db5490224df2329f" + "f0e573c85e3ea01049704b74ce33a7dbd93a01c3bee19c095927e0ebcc7aa36c57fb5467b20a8f10" + "b64da6ee21db688ead98671784d9972a155568268b372c9cfaa86e6d5b58f7e345d66751614d7740" + "f449c7f7b50e63b2d2d441c77d32997f17a1c62636b9855a238cfc1cad090dbe906882b1985fb814" + "b4b5ecf73a0f19fac21ffbc93a1cb618c4d6bac70a9d0df562b0d63d6c3f0f6e352c2c3d45af9c11" + "b9b68ed0481fdf1f3dd326b31b3ead81128a0ad1b481e48cb2615df6be7c595f11d679abada7c9ac" + "78f63867372b9861e97c24dedd1f11d0c26ede74d101af10c0c53e6ce423ebf8fa3d61600f0fe381" + "923ea8638382afa6144dbec8ef980beb856ea34541ebc708af409256df0c9d8a667739cb57641cbe" + "f9e35d497929ee67e4a77296c8c020b3eeda0ab81c77bd43536c82c130dd657a570e78a695a0007e" + "1470e8d66be7a20b87de45d5e89e5c403892ec48460f156db05141f2a4a15d53c02ad0dedb371d7d" + "b9c5e41130d7924130b9573943a5b4574b1f229e8867ef2bd58a3df0c59358407b416b411098da16" + "036831c54a8368b2479bb90e6b7c28ed1b5a1db5e12b4aa6b6a1bc86ae615eb3b1d6ae9e7a6f420d" + "48f34f95bb953ef29242b12263660b9a590172ce21c8bdce6bdc284512708a318cf015fcc52e016b" + "e3571af346ac3f5bf7a65529e78670c75f9782d55a610baa39e728f0d11ab153a1b86b6b1f480c33" + "7ca56975ca49e70867c6e2a396c5fd8fb61f4b7a3b75e1f1e82a8fbdb5a47daa631df4e2d2bbd283" + "a0b1687e71d9371d23fe1e39d5d8bb70c2a734f88d69a3691beeea8953f8862eb3e3619e173b40e6" + "81bd95f01858b596c6f7162753a880fe6174c550dab1d6b94cde227216552cb14ee6caeaadf4c5bc" + "5994570c7e8308665e6e789308bb16aa1996bc58daafa45767bd51480415497d321b587addb0664c" + "c8ecf217f70c17dc2b3b437bb371129598bd11165d7e023ec5bfd2da72a379eac8e19ebef1ba23a8" + "eaaf3ab712e2e1cc30e6bfe17b619b30167c4c613e8de82a95ee3135829c53dde747fc1faa90d290" + "f05d820b347ed7076abd24e8091b360c3277d7f59903b5f5fa636c63a34c9b59c2d353ee160555d7" + "c4dbe72d3252edc6aacc717a8ca87c150c156103b5a635696c0d12acbcab6138dcb548f01cce73f5" + "7b964eb1ed6b38b15aac4c566e058b91a2ab38fcb8d90211a4a06aa18b7c02145bed5584deeddf66" + "e9837e88b4deddc56e5cd73f51159541cdace7424a71fd11d547a4361c7a4c4ae78de4ec70fdebeb" + "3e429b79cd65c058e06a22ca070287a8b59738f19d52672de8f54aadb9b2b6a5f05f78e1f1f515ff" + "9ccea9dc957e0e1ad659b207f5980028fe2771c4652adcb39d899abbaef5c61323fc5d326c4afc8d" + "a99bb8144c24b60f7de03a2e907d839ad1ab286c53dfda3ca481a2cf958005eb4e24b7819b441c97" + "c8c9801c46864714e2af4eacf36954b13e400c75b73b6e9eeefe593c9122070304287b1c7ed06e75" + "d0801b098ace8efa33434f4578a1da6d17cafe33dc0ec690d9af484a1bb6d12758ce7cfa66935376" + "907a822496e7ad7f1508d9c7367a672bff9f97fcce9c0cccb995b4ed1bf6b3a361afad133c804c5a" + "e7b72e3ae5565eb56ce6df53dfcb6c1fdec116ec93e38c1dda9793e4c182cf3e90b6db307fa35d46" + "8078675c9fe5a27b8445d0b23a4b628e676fd8ee4e0b0ed555e37e34be82f37f140ba15073d494c8" + "ae1280907c7477f300bb7fcbb936b2105e5d00cbc39853ae9bb424e3d9c07ba873637fee4c33eaf1" + "7cbbb6ca6d2abab12dc7a75f4004aa75efde94465883d85faf201959678bf73929bf8f2f0403b9d4" + "c20fe6f8967a979809706bdba48859d1ce710129118f57234599a3e22270e035a7722404e50c5784" + "4d729690b9749e3786b969fd783ec7a8c008d9ddb2fad1bcaae1995dec82a3ee8092c269333392a5" + "46de7b949a7cb65a6bf1adc89dc5515bef8819d8dee3341792db070066aacbf60da2dd5b8ab47f2e" + "4bdd00762e8847f47ebd2241120c0616df6fd6e5ea854267a0fe3c802910ea843b64831d94b48818" + "2c54bf7ea3bcfd77fa41124a2858ff8bdf81378904aff993ea3b1a211fb65c2df8b78d34d8f4b3a0" + "9e8b474d1ab8d5d7d332b150ce5db7d720a18cbbee9bd5b2db243a678e90600a66e5ef7280128e9a" + "35ea8aa0c095b8507e87cb980d2e7a04d4bc047ab145314b2b235558e1e396f2a648738a77a9839a" + "e37985c13051e3d7aa4b05b90be338c34fbb7ab6c142896635466c091f0f296756b1ed19558d16e0" + "38a59f5cfd120e96d79dc44cc16cd8e5250b1d61bb2a714802c1a87ba0fb5e70677c7a0fc4bca3b9" + "24ce793d78c3b0359725d4c588bd60066dcf0a23c8a86990200bec5ca54796de29e10fbf77f5eea1" + "43a38e6a6e1fea0b03c95cfa224edf2ac1867c142b64fe90179b023fe1f50005538cd8a92dfefbca" + "75d8e3ec492d53b5aeadd72981328542eb0903aaf2fc09daaf27fe4fc8b5cca6af18e0026cd2f244" + "d8aafbfb11f0270ba511c4b0d805d5088d6a4a3a59aeb2361ae3027cb5b902ed55fde38c164ca450" + "013bf02d2483a1b61f2bedd31966bbf8dd1c972ef029dd3dd3b74fe78d6ac1edb98d1815a22f3bcc" + "c206d470c26797d2917ed5316b956c6e928e159294d41d478a40a4af2acd3a294b3be55fa50e44bf" + "e9785dd5383ea759777cfb7b9d316fc40c9abf1f6d5b34f89e433395b0bf5e07e6962ea278e22b4a" + "da97db479201472722c682292a1f0107e12c8e1348aff941bb5158da7ca9bface061b22e22e8ba9f" + "9700af4a155b7bc378dcca96d9aee391a6349be9c668f40b2dc4107c76239b4fd89cec57c334e603" + "4e6afa183015d5010f296457f9d0f04713296b73095165c81601e36dc962d0527dc5a81593821f62" + "292fd1fab21d2fc3a2f884e0a9689ceb2eade3486e8d976b65684d40954d681f94df9992a273c915" + "383786ec557d8f41c42a2efea133b57946f45ea1b627d5a79c72daca84ffbb811ab37874086e25e5" + "b1601e0038505fca4394258c60075dab3285fca7b3e267c66731f1b165607b937c4606baee2d2dbe" + "0397c623bbfee94bc3c42a579100daeb867efd9ddc49e0ea5881898c733d5aa122a9a6ad9d5e6009" + "20dd674466d5886d94e6346c56a55af08218e136fc2a3849ec60e95f9d1b6df81517007f9bca7b84" + "e624a09f4be514cfb3e3dff2f00436aa19571a1e4674785a15d31aaf01a2091f3e752b29638e84ab" + "7e5bc993086ef027c9aa311464189d9c63659691367fa5c56c2cf4e1b485b55dad9678aa85529092" + "2734abb7b398f1dcf82a52960b21661bf32b783a40f86ad013ad573c64a02743427b9e4ce0eb703a" + "9280de7471bb03fa8a5a57c6025bc277fd28616040ebfae77471e988f8feb5a2db90f8c5a3fc4b3b" + "d0b3f2ffd239966dbff3431bcfd5afd18d6bfc100c7d4476b264c636e2c73e5aa42cec510e0897b9" + "465b3dfa6e7ac9686d5f6484cfe908f751909c3f095872645b9fd4f21776a713bd1b574c250c7012" + "cdf8e16fe1140fed49fc8db0185cbafb347cf2c4538ff867061bb37ed0b1c324f99c46764f93a345" + "488279b787276688981c7c4519447f0468ae1d9b21f6b232ca8f9c6b58b1262e5634ffcc3d87db73" + "4580a28b6944703eeb6f01f624e113606df3b0128a6e546a0fdf83c0fd265b72ed8158968cf1f807" + "0eec6ca64376c84985a7d1de07b201bd6cc7312067b692e6d43fcbe9555632ebe33070f04497c96e" + "263c9766af8b336cd939e9c51351551c26536289f61b2a01408056a097d760238bcfc355f052d0e6" + "edf3f4910525ccb4b9c92f54af067a9624d064719b7f7e6ee05065f2575913c78b25b743c474a289" + "4256013b24d5dcc65e439adca947c4bc624655f25a3d60a08367846717d66d7626d2bb9e104bcdaa" + "9ce7a6d06354d306bdf891de3e563d2132083028c79d2c5624f9a39075bd2923dd34d071ed678c25" + "9d96714f8ac55ca965cde19e3081ef7f955e24c035bc125a7f43c7986dcbbfcfac8dec2af5ae3d95" + "e88e6b8e11bd323221a2d247e3ad39d894466dffc0d77f4dd01667d11f219d2fa78945a74bec99d5" + "770960bece320ce82e0fa1a82378c52b1d3f88dd250a630e3c114a12f0f6a591ed9d6e82644c7c51" + "54d46579acf60996704bead6998623403e978b04b3dd0b923d8a7d2ee79e482ea804c21a7eed2fa9" + "7f5ae85e34bcf9cea425b73ff306986bdae5b7d94b5b1a534a76afb4b9663813b3de1048aca6e1f1" + "87805ba66b511d7a2a47c24ec66f2b96898e2f7436fd750c1f349ecf5c546d8d39c440074ee84aff" + "109cdb0eb35d3e3c7c11abdc6ad1cc2ab386480bad679b503c3877033628d0e07d5429a1cfd71b94" + "97d65dc90ce540718383a3657dfe4e6c305633dc0698d02777fb898a8ca0ddcea37c96d405067e23" + "477fe636c26b086bceb02443080b8837f4350640d7ebeb227ac6e71ecb8140e129dd6b9db5bea5bd" + "eac8aac6ab7b8311127e516dd0bec2747a1ecaeaf3794407d0a73e315dac690850808c94bcbc49b8" + "8b272ff59373c5cf9a8e0c442c0eb7829faa1f1c394e566ea444d523194bd1547b56cfbaec82aa05" + "d8909697c49f066f28484a8c7bb4c34584946084e294532c9bd704a8e125f1ede4fa86604c9d2109" + "12d2326a94ff1edbba1231c848b84f5f9399b17b600cf1586e9efe686686e7f449ce3f820f051583" + "4508f1cf10efcffd014cb65cba99a8534f6ae2c987fc69f152e70ce03b32663dd485015a0d956cfd" + "9696588b45674b42f8eb6d58a167de1003c2144d1fde87e1097fa4264b1e0249fb2bec3c780094f6" + "c73b2a69a1e9c5806ad26ea0fbcfb68dcc2970b0e913b5ed41654366202230096abf925df05dd9c2" + "cf706127364ed8519d8bc51de85887db051b22e1de6ee18849cb85188d453952d02d5b7717257b49" + "9292446f68dbece07c5422e790f40b3f21f996133e0c62fc6046c003aa4c679fc924556c45623378" + "10d1b60fd750fbc1ebc9a9ae9c66ed4b94c790dbbdae6b81ede8ced06c33fe5da09b99e82b9195bc" + "d60b4502fc7384fe1fd9d30bfccb27ba303b301f300706052b0e03021a0414809543226a23c6d9d8" + "e1c872577d5ef35c4e87c10414b0e8c9d74969d069f12daa9d61e381229ea02dc4020207d0" +) TEST_CERTIFICATE_PASS = b"password" -TEST_AUTH_VAR_PKCS7 = "e7070202130b0f000000000000000000690600000002f10e9dd2af4adf68ee498aa9347d375665a7" \ - "3082064d020101310f300d06096086480165030402010500300b06092a864886f70d010701a08204" \ - "a5308204a130820289a00302010202101b33e7414b6935924d6570b3ef3bcff2300d06092a864886" \ - "f70d01010b05003040313e303c06035504030c355661726961626c65204b6579204c656e67746820" \ - "537570706f7274204f3d636f6e746f736f204f553d496e7465726d656469617465301e170d323330" \ - "3230333033303131345a170d3333303230333033313131345a303a3138303606035504030c2f5661" \ - "726961626c65204b6579204c656e67746820537570706f7274204f3d636f6e746f736f204f553d53" \ - "69676e657230820122300d06092a864886f70d01010105000382010f003082010a0282010100b0e6" \ - "18daf60f6ff2f4ae6f787e8eecbec0ba920972cce3476f3d87ec3a8a58c8b912b3493494e4741621" \ - "b9f5da4f7be89e99dd28ea6682fa05bc5d414305316e7b1d44473a0983f7dbcd5bec2c8be0b9bcf4" \ - "e15e830283e1c76c2bd4d9b1f75b78a59a01b9dc3cdc82e86bf96fd09245dd9965944890a1028718" \ - "c7e3d30b4f4ad60b607f6d414a835d68d87809d5f758be4c08d101d25da748ab24cd155affc9de63" \ - "2af705375336e87bd322891ae84ade1f490c6707de337f9f17429a5d291e24ee6ba22468fa9dff6b" \ - "5d3ce9b2aad5b384c1d53aecf468aaf61fd9026d2869705d5570699b2dc24cdf27bbadf8a4b90390" \ - "a42852c01c9f87432cf239433b8d0203010001a3819c308199300e0603551d0f0101ff0404030201" \ - "06301d0603551d250416301406082b0601050507030206082b06010505070301301a0603551d1104" \ - "133011820f7777772e636f6e746f736f2e636f6d300c0603551d130101ff04023000301f0603551d" \ - "23041830168014ddfb4fbfd41c16fef8e21e42aa118e72425da7d8301d0603551d0e04160414b5ce" \ - "51b88d501f046d4b85e707adb32e56335919300d06092a864886f70d01010b0500038202010069b4" \ - "c7fd83c1767a7faa17a5f0137d58b6a9d3e4006fd7cc3cb89c192ca8c8b4a3f41b56608a1a7fc534" \ - "6d734921e4a28466c6046b399b01393107732ffada0ef2fb1cbb1768d55cda8fd7fb7c05d31637d4" \ - "62c212fe0b3ee23d92b6209a737acef61861e2fe3f1d4ee035220008d973de7251f5f7a760382559" \ - "ac766046f8ac10f8c9dd8cdd5c491caa91549bbfbd1f23ec3ceb962ac8f4d34b8630e203066eaea7" \ - "62c06a2f5da0be945cad726aa2f187736b6b0acaa162e3caf4d337c3001cce56f77a4ae78619c514" \ - "c95e6ef53f26d39db21e393caa7fd41dc526b3a1ec9220bf21a934e77ba41c177adfdaef7876e62e" \ - "dadcb0048dd4bbf6b41b8527feca01d5e5fa9361796caa265bf2ee96e6700985f9c11811efe7aed1" \ - "2afb6a5e683ae426d9040fa7aca31701da19d1037851828c6ce2d966d723f11d9b83216f7df6141f" \ - "2a65698b27bceb9fc8d6f16ddbb50b527ff0dd2ea9e3fe45d23183af8f03b01e51f2b64e7897f360" \ - "0a0cf2aad6870f3a998d853bde24bc8d25d8d9f9e430730d353ea41db8dbfe2de420fbd450142d18" \ - "2e2f22f42930d40480fa56da4ccb2e71b8de5d429d83234698c5ded598cb9e109493bac5918e6fd9" \ - "50b367a54d16b725664ea0ba929697739dd93d4d77aedd6e1b96051d5521e0c19595e4196172d344" \ - "69044f6a979efce671a1ac8d73ca3bbfa675220c399ba1d1d8dcac4a76683182017f3082017b0201" \ - "0130543040313e303c06035504030c355661726961626c65204b6579204c656e6774682053757070" \ - "6f7274204f3d636f6e746f736f204f553d496e7465726d65646961746502101b33e7414b6935924d" \ - "6570b3ef3bcff2300d06096086480165030402010500300d06092a864886f70d01010b0500048201" \ - "0043699097d5dc6326225e9d72d11714b97706d701f7eee12d019d1039aae2553a77e6d41ca115e6" \ - "27ec0985c30cdf8cd1872f72240c313a7df0ee29e3f8d96b925edb0822166d0231600a7dea0c73d6" \ - "54fc9b3eb3346f76c7160cdef053f72e4fc66a2263d034b7535d775da2ac0f04f0291118265a22f0" \ - "21ed8e408ed74e1e015f90df6660f4f5514b041ac8fb4fe8d6b6dc6fdc5e04646838b1b1849f4753" \ - "80ee86a97c6bb39d9df0254ee201e27338ade008e2af7ee739fc86fcd99101c33340adbbf5ebba60" \ - "c74c7d0c162de7880a26641a780e41b4cbbaacbe19fc96e1f04dd72b2b67de35482fcba42181a540" \ - "173ec21cfbaa7aa99e491cd0f91fa559a5546573743a205661726961626c654b65794c656e677468" \ - "537570706f7274202d204465736372697074696f6e3a205369676e65642042792032303438204365" \ - "727469666963617465" +TEST_AUTH_VAR_PKCS7 = ( + "e7070202130b0f000000000000000000690600000002f10e9dd2af4adf68ee498aa9347d375665a7" + "3082064d020101310f300d06096086480165030402010500300b06092a864886f70d010701a08204" + "a5308204a130820289a00302010202101b33e7414b6935924d6570b3ef3bcff2300d06092a864886" + "f70d01010b05003040313e303c06035504030c355661726961626c65204b6579204c656e67746820" + "537570706f7274204f3d636f6e746f736f204f553d496e7465726d656469617465301e170d323330" + "3230333033303131345a170d3333303230333033313131345a303a3138303606035504030c2f5661" + "726961626c65204b6579204c656e67746820537570706f7274204f3d636f6e746f736f204f553d53" + "69676e657230820122300d06092a864886f70d01010105000382010f003082010a0282010100b0e6" + "18daf60f6ff2f4ae6f787e8eecbec0ba920972cce3476f3d87ec3a8a58c8b912b3493494e4741621" + "b9f5da4f7be89e99dd28ea6682fa05bc5d414305316e7b1d44473a0983f7dbcd5bec2c8be0b9bcf4" + "e15e830283e1c76c2bd4d9b1f75b78a59a01b9dc3cdc82e86bf96fd09245dd9965944890a1028718" + "c7e3d30b4f4ad60b607f6d414a835d68d87809d5f758be4c08d101d25da748ab24cd155affc9de63" + "2af705375336e87bd322891ae84ade1f490c6707de337f9f17429a5d291e24ee6ba22468fa9dff6b" + "5d3ce9b2aad5b384c1d53aecf468aaf61fd9026d2869705d5570699b2dc24cdf27bbadf8a4b90390" + "a42852c01c9f87432cf239433b8d0203010001a3819c308199300e0603551d0f0101ff0404030201" + "06301d0603551d250416301406082b0601050507030206082b06010505070301301a0603551d1104" + "133011820f7777772e636f6e746f736f2e636f6d300c0603551d130101ff04023000301f0603551d" + "23041830168014ddfb4fbfd41c16fef8e21e42aa118e72425da7d8301d0603551d0e04160414b5ce" + "51b88d501f046d4b85e707adb32e56335919300d06092a864886f70d01010b0500038202010069b4" + "c7fd83c1767a7faa17a5f0137d58b6a9d3e4006fd7cc3cb89c192ca8c8b4a3f41b56608a1a7fc534" + "6d734921e4a28466c6046b399b01393107732ffada0ef2fb1cbb1768d55cda8fd7fb7c05d31637d4" + "62c212fe0b3ee23d92b6209a737acef61861e2fe3f1d4ee035220008d973de7251f5f7a760382559" + "ac766046f8ac10f8c9dd8cdd5c491caa91549bbfbd1f23ec3ceb962ac8f4d34b8630e203066eaea7" + "62c06a2f5da0be945cad726aa2f187736b6b0acaa162e3caf4d337c3001cce56f77a4ae78619c514" + "c95e6ef53f26d39db21e393caa7fd41dc526b3a1ec9220bf21a934e77ba41c177adfdaef7876e62e" + "dadcb0048dd4bbf6b41b8527feca01d5e5fa9361796caa265bf2ee96e6700985f9c11811efe7aed1" + "2afb6a5e683ae426d9040fa7aca31701da19d1037851828c6ce2d966d723f11d9b83216f7df6141f" + "2a65698b27bceb9fc8d6f16ddbb50b527ff0dd2ea9e3fe45d23183af8f03b01e51f2b64e7897f360" + "0a0cf2aad6870f3a998d853bde24bc8d25d8d9f9e430730d353ea41db8dbfe2de420fbd450142d18" + "2e2f22f42930d40480fa56da4ccb2e71b8de5d429d83234698c5ded598cb9e109493bac5918e6fd9" + "50b367a54d16b725664ea0ba929697739dd93d4d77aedd6e1b96051d5521e0c19595e4196172d344" + "69044f6a979efce671a1ac8d73ca3bbfa675220c399ba1d1d8dcac4a76683182017f3082017b0201" + "0130543040313e303c06035504030c355661726961626c65204b6579204c656e6774682053757070" + "6f7274204f3d636f6e746f736f204f553d496e7465726d65646961746502101b33e7414b6935924d" + "6570b3ef3bcff2300d06096086480165030402010500300d06092a864886f70d01010b0500048201" + "0043699097d5dc6326225e9d72d11714b97706d701f7eee12d019d1039aae2553a77e6d41ca115e6" + "27ec0985c30cdf8cd1872f72240c313a7df0ee29e3f8d96b925edb0822166d0231600a7dea0c73d6" + "54fc9b3eb3346f76c7160cdef053f72e4fc66a2263d034b7535d775da2ac0f04f0291118265a22f0" + "21ed8e408ed74e1e015f90df6660f4f5514b041ac8fb4fe8d6b6dc6fdc5e04646838b1b1849f4753" + "80ee86a97c6bb39d9df0254ee201e27338ade008e2af7ee739fc86fcd99101c33340adbbf5ebba60" + "c74c7d0c162de7880a26641a780e41b4cbbaacbe19fc96e1f04dd72b2b67de35482fcba42181a540" + "173ec21cfbaa7aa99e491cd0f91fa559a5546573743a205661726961626c654b65794c656e677468" + "537570706f7274202d204465736372697074696f6e3a205369676e65642042792032303438204365" + "727469666963617465" +) # Here is an example of how to generate an RSA2048 SHA256 hash using OpenSSL: