diff --git a/dissect/cstruct/compiler.py b/dissect/cstruct/compiler.py index 296d944..2ea6778 100644 --- a/dissect/cstruct/compiler.py +++ b/dissect/cstruct/compiler.py @@ -1,5 +1,6 @@ from __future__ import annotations +import keyword import struct from collections import OrderedDict from textwrap import dedent @@ -75,6 +76,8 @@ def compile(self, structure: Structure) -> Structure: return structure structure_name = structure.name + if keyword.iskeyword(structure_name): + structure_name += "_" try: # Generate struct class based on provided structure type @@ -104,7 +107,9 @@ def compile(self, structure: Structure) -> Structure: } exec(code_object, env) - return env[structure_name](self.cstruct, structure, source) + klass = env[structure_name] + klass.__name__ = structure.name + return klass(self.cstruct, structure, source) def gen_struct_class(self, name: str, structure: Structure) -> str: blocks = [] diff --git a/tests/test_basic.py b/tests/test_basic.py index 3b8b9ea..5ed33eb 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -546,3 +546,28 @@ def test_report_array_size_mismatch(): with pytest.raises(ArraySizeError): a.dumps() + + +@pytest.mark.parametrize("compiled", [True, False]) +def test_reserved_keyword(compiled: bool): + cdef = """ + struct in { + uint8 a; + }; + + struct class { + uint8 a; + }; + + struct for { + uint8 a; + }; + """ + cs = cstruct.cstruct(endian="<") + cs.load(cdef, compiled=compiled) + + for name in ["in", "class", "for"]: + assert name in cs.typedefs + assert verify_compiled(cs.resolve(name), compiled) + + assert cs.resolve(name)(b"\x01").a == 1