From b546bb10eae52da3a7dd06d8de0863f93775835f Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Fri, 18 Jul 2025 11:16:45 +0200 Subject: [PATCH 1/2] Add support for combined name and pointer typedef --- dissect/cstruct/parser.py | 4 ++-- tests/test_parser.py | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/dissect/cstruct/parser.py b/dissect/cstruct/parser.py index 73465d5..8f214f6 100644 --- a/dissect/cstruct/parser.py +++ b/dissect/cstruct/parser.py @@ -314,11 +314,11 @@ def _names(self, tokens: TokenConsumer) -> list[str]: tokens.eol() break - if tokens.next not in (self.TOK.NAME, self.TOK.DEFS): + if tokens.next not in (self.TOK.NAME, self.TOK.DEFS, self.TOK.IDENTIFIER): break ntoken = tokens.consume() - if ntoken == self.TOK.NAME: + if ntoken in (self.TOK.NAME, self.TOK.IDENTIFIER): names.append(ntoken.value.strip()) elif ntoken == self.TOK.DEFS: names.extend([name.strip() for name in ntoken.value.strip().split(",")]) diff --git a/tests/test_parser.py b/tests/test_parser.py index 3e28549..d049756 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -7,7 +7,7 @@ from dissect.cstruct.exceptions import ParserError from dissect.cstruct.parser import TokenParser -from dissect.cstruct.types import BaseArray, Pointer +from dissect.cstruct.types import BaseArray, Pointer, Structure from tests.utils import verify_compiled if TYPE_CHECKING: @@ -149,3 +149,18 @@ def test_includes(cs: cstruct) -> None: assert cs.myStruct.__name__ == "myStruct" assert len(cs.myStruct.fields) == 1 assert cs.myStruct.fields.get("charVal") + + +def test_typedef_pointer(cs: cstruct) -> None: + cdef = """ + typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; + } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + """ + cs.load(cdef) + + assert issubclass(cs._IMAGE_DATA_DIRECTORY, Structure) + assert cs.IMAGE_DATA_DIRECTORY is cs._IMAGE_DATA_DIRECTORY + assert issubclass(cs.PIMAGE_DATA_DIRECTORY, Pointer) + assert cs.PIMAGE_DATA_DIRECTORY.type == cs._IMAGE_DATA_DIRECTORY From 70898f7c7768fd0c354ae0c3ee11342817e71430 Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:22:40 +0200 Subject: [PATCH 2/2] Fix stub generation for struct pointers --- dissect/cstruct/tools/stubgen.py | 3 +++ tests/test_tools_stubgen.py | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/dissect/cstruct/tools/stubgen.py b/dissect/cstruct/tools/stubgen.py index 8f30b6a..75694e3 100644 --- a/dissect/cstruct/tools/stubgen.py +++ b/dissect/cstruct/tools/stubgen.py @@ -92,6 +92,9 @@ def generate_cstruct_stub(cs: cstruct, module_prefix: str = "", cls_name: str = stub = f"{name}: TypeAlias = {typedef.__name__}" elif issubclass(typedef, (types.Enum, types.Flag)): stub = generate_enum_stub(typedef, cs_prefix=cs_prefix, module_prefix=module_prefix) + elif issubclass(typedef, types.Pointer): + typehint = generate_typehint(typedef, prefix=cs_prefix, module_prefix=module_prefix) + stub = f"{name}: TypeAlias = {typehint}" elif issubclass(typedef, types.Structure): stub = generate_structure_stub(typedef, cs_prefix=cs_prefix, module_prefix=module_prefix) elif issubclass(typedef, types.BaseType): diff --git a/tests/test_tools_stubgen.py b/tests/test_tools_stubgen.py index 097cae8..5790d90 100644 --- a/tests/test_tools_stubgen.py +++ b/tests/test_tools_stubgen.py @@ -319,6 +319,26 @@ class cstruct(cstruct): """, id="define literals", ), + pytest.param( + """ + typedef struct _Test { + uint8 a; + } Test, *pTest; + """, + """ + class cstruct(cstruct): + class _Test(Structure): + a: cstruct.uint8 + @overload + def __init__(self, a: cstruct.uint8 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + Test: TypeAlias = _Test + pTest: TypeAlias = Pointer[cstruct._Test] + """, + id="pointer alias", + ), ], ) def test_generate_cstruct_stub(cs: cstruct, cdef: str, expected: str) -> None: