From 0dca127649a2060a5a8f1601ceeada3baa47d172 Mon Sep 17 00:00:00 2001 From: MS Date: Sun, 9 Jun 2024 13:52:04 -0400 Subject: [PATCH] Parse anonymous LF_UNION type (#1013) --- tools/isledecomp/isledecomp/cvdump/types.py | 5 +++-- tools/isledecomp/tests/test_cvdump_types.py | 23 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/tools/isledecomp/isledecomp/cvdump/types.py b/tools/isledecomp/isledecomp/cvdump/types.py index 381c27e9..b39ea248 100644 --- a/tools/isledecomp/isledecomp/cvdump/types.py +++ b/tools/isledecomp/isledecomp/cvdump/types.py @@ -221,7 +221,7 @@ class CvdumpTypesParser: ) LF_ENUM_UDT = re.compile(r"^\s*UDT\((?P0x\w+)\)$") LF_UNION_LINE = re.compile( - r"^.*field list type (?P0x\w+),.*Size = (?P\d+)\s*,class name = (?P(?:[^,]|,\S)+),\s.*UDT\((?P0x\w+)\)$" + r"^.*field list type (?P0x\w+),.*Size = (?P\d+)\s*,class name = (?P(?:[^,]|,\S)+)(?:,\s.*UDT\((?P0x\w+)\))?$" ) MODES_OF_INTEREST = { @@ -659,4 +659,5 @@ class CvdumpTypesParser: self._set("is_forward_ref", True) self._set("size", int(match.group("size"))) - self._set("udt", normalize_type_id(match.group("udt"))) + if match.group("udt") is not None: + self._set("udt", normalize_type_id(match.group("udt"))) diff --git a/tools/isledecomp/tests/test_cvdump_types.py b/tools/isledecomp/tests/test_cvdump_types.py index e271040c..324870eb 100644 --- a/tools/isledecomp/tests/test_cvdump_types.py +++ b/tools/isledecomp/tests/test_cvdump_types.py @@ -551,3 +551,26 @@ def test_fieldlist_enumerate(parser: CvdumpTypesParser): {"name": "c_text", "value": 4}, ], } + + +UNNAMED_UNION_DATA = """ +0x369d : Length = 34, Leaf = 0x1203 LF_FIELDLIST + list[0] = LF_MEMBER, public, type = T_32PRCHAR(0470), offset = 0 + member name = 'sz' + list[1] = LF_MEMBER, public, type = T_32PUSHORT(0421), offset = 0 + member name = 'wz' + +0x369e : Length = 22, Leaf = 0x1506 LF_UNION + # members = 2, field list type 0x369d, NESTED, Size = 4 ,class name = __unnamed +""" + + +def test_unnamed_union(): + """Make sure we can parse anonymous union types without a UDT""" + parser = CvdumpTypesParser() + for line in UNNAMED_UNION_DATA.split("\n"): + parser.read_line(line) + + # Make sure we can parse the members line + union = parser.keys["0x369e"] + assert union["size"] == 4