diff --git a/src/xmlcli/common/bios_fw_parser.py b/src/xmlcli/common/bios_fw_parser.py index 49a8176..00626fd 100644 --- a/src/xmlcli/common/bios_fw_parser.py +++ b/src/xmlcli/common/bios_fw_parser.py @@ -460,7 +460,12 @@ def parse_ffs_section(self, buffer, buffer_pointer, end_point, ffs_data, _type, buffer.seek(align_buffer) section = structure.section_finder(buffer=buffer, buffer_pointer=align_buffer) # parse valid section from buffer log.debug(section) - key = f"0x{align_buffer:x}-{'SEC'}-0x{section.get_section_size():x}" # construct key to store fv values + section_size = section.get_section_size() + if section_size == 0: + err_msg = f"Encountered zero-length section at 0x{align_buffer:x} in FFS {ffs_guid}" + log.error(err_msg) + return result + key = f"0x{align_buffer:x}-{'SEC'}-0x{section_size:x}" # construct key to store fv values # construct section tuple if valid section type section_tuple = structure.FFS_SECTION_TYPE_MAP.get(section.section_type) if not section_tuple: @@ -503,7 +508,7 @@ def parse_ffs_section(self, buffer, buffer_pointer, end_point, ffs_data, _type, result[key]["FV"] = self.sort_output_fv(result[key]["FV"]) log.debug(f"Aligned buffer: 0x{align_buffer:x}") - align_buffer += section.get_section_size() + align_buffer += section_size log.debug(f"Incremented Aligned buffer: 0x{align_buffer:x}") align_buffer = utils.round_up(align_buffer, structure.SECTION_ALIGNMENT) log.debug(f"Aligned buffer at 0x{structure.SECTION_ALIGNMENT:x} bytes: 0x{align_buffer:x}") diff --git a/tests/UefiParserTest.py b/tests/UefiParserTest.py index 9885ae5..c7f82d0 100644 --- a/tests/UefiParserTest.py +++ b/tests/UefiParserTest.py @@ -3,9 +3,12 @@ # Built-in imports import os import sys +import io import shutil import warnings import unittest +from types import SimpleNamespace +from unittest import mock warnings.simplefilter("ignore", ResourceWarning) @@ -33,6 +36,29 @@ def test_guid_structure_read(self): class UefiParserTest(UnitTestHelper): + def test_zero_length_section_terminates_parsing(self): + parser = bios_fw_parser.UefiParser.__new__(bios_fw_parser.UefiParser) + parser.parsing_level = SimpleNamespace(level=0) + ffs_data = SimpleNamespace(Name=SimpleNamespace(guid="test-guid"), size=0x100) + buffer = io.BytesIO(b"\x00" * 8) + section_finder = structure.section_finder + calls = [] + + def find_section_once(buffer, buffer_pointer): + calls.append(buffer_pointer) + if len(calls) > 1: + raise AssertionError("section parser did not advance past a zero-length section") + return section_finder(buffer, buffer_pointer) + + with mock.patch.object(bios_fw_parser.utils, "store_buffer"), \ + mock.patch.object(structure, "section_finder", side_effect=find_section_once), \ + mock.patch.object(bios_fw_parser.log, "error") as log_error: + result = parser.parse_ffs_section(buffer, 0, 8, ffs_data, "FV_FILETYPE_FREEFORM", 0, False) + + self.assertEqual(result, {}) + self.assertEqual(calls, [0]) + log_error.assert_called_once_with("Encountered zero-length section at 0x0 in FFS test-guid") + guid_lis1 = [ # GUIDs available in ADL_FSP_0496_00_D.rom (may exist in other rom) "fc8fe6b5-cd9b-411e-bd8f31824d0cde3d",